Filter results by

ARTIK 053 as MQTT Publisher

Now that you're familiar with using the ARTIK 053 module as an MQTT subscriber, let's take a quick look at the publish aspect.

In this tutorial, we use the ARTIK IDE to augment your previous MQTT subscriber program to add MQTT publishing capabilities. To give it some data to publish, we'll start by wiring a simple photosensor device to an analog port of the module. Then we'll put in code to read the analog value and publish periodic updates of the value being sensed.

Prerequisites

You will need the same MQTT broker setup as in the previous article. We'll be starting from that previous code and just adding in snippets for the additional functionality.

Set Up Publisher Edge Device

We will use the same ARTIK 053 module as before for our edge device.

  1. In the ARTIK IDE, open your existing ARTIK 053 MQTT project.

  2. Select the main.c tab. You'll be doing all your changes there.

  3. Add the following header file lines to your existing list.
    #include <tinyara/analog/adc.h>
    #include <tinyara/analog/ioctl.h>

  4. Add this onPublish callback function, which gets called every time a message is sent, after the existing onDisconnect callback.

    // mqtt client on publish callback
    void onPublish(void* client, int result) {
       printf("mqtt client Published message\n");
    }

  5. Add a corresponding onPublish declaration to the existing initializeConfigUtil routine.
      clientConfig.on_connect = (void) onConnect;
      clientConfig.on_disconnect = (void
    ) onDisconnect;
      clientConfig.on_message = (void*) onMessage;
    clientConfig.on_publish = (void*) onPublish;

  6. Include the logic and code to read analog data from the sensor and publish the same on the topic of “brightness”.
    Replace the existing block
    while(1) {
    }
    with the following block of code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Read analog signal using ADC
int fd;
struct adc_msg_s sample;
size_t readsize;
ssize_t nbytes;
int publishedVal = -1;

fd = open("/dev/adc0", O_RDONLY);
if (fd < 0) {
    printf("%s: open failed: %d\n", __func__, errno);
    return 0;
}

while(1) {
    usleep(10000);
    ret = ioctl(fd, ANIOC_TRIGGER, 0);
    if (ret < 0) {
        printf("%s: ioctl failed: %d\n", __func__, errno);
        close(fd);
        return 0;
    }

    readsize = sizeof(struct adc_msg_s);

    // adc_msg_s structure returns the data structure containing analog readings from ADC pins
    nbytes = read(fd, &sample, readsize);
    if (nbytes < 0) {
        if (errno != EINTR) {
            printf("%s: read failed: %d\n", __func__, errno);
            close(fd);
            return 0;
        }
    } else if (nbytes == 0) {
        printf("%s: No data read, Ignoring\n");
    } else {
        int nsamples = nbytes / sizeof(struct adc_msg_s);
        if (nsamples * sizeof(struct adc_msg_s) != nbytes) {
            printf("%s: read size=%ld is not a multiple of sample size=%d, Ignoring\n", __func__, (long)nbytes, sizeof(struct adc_msg_s));
        } else {
            // Filter the data obtained from only ADC pin connected to the sensor A0 - 0, A1 - 1, A2 - 2, A3 - 3
            if ((sample.am_channel == 0) && ((sample.am_data > (publishedVal + 100)) || (sample.am_data < (publishedVal - 100)))) // A0 ADC
            {
                printf("Publish message for signal A0\n");
                char buf[4];
                sprintf(buf,"%d",sample.am_data);
                char* msg = buf;
                // construct the mqtt message to be published
                mqtt_msg_t message;
                message.payload = msg;
                message.payload_len = strlen(buf);
                message.topic = "brightness";
                message.qos = 0;
                message.retain = 0;
                ret = mqtt_publish(pClientHandle, message.topic, (char*)message.payload, message.payload_len, message.qos, message.retain);
                if (ret < 0) {
                    printf("Error publishing \n");
                }
                else {
                    publishedVal = sample.am_data;
                }
            }
        }
    }
}
close(fd);

   7. Save the file.

   8. Build the code as usual.

When you flash-load the code and if all goes well, you will see values from the 'brightness' topic arrive at your broker on a periodic basis. It won't signify anything, because we haven't yet connected an analog sensor.

Build Photosensor Circuit

To create the input circuit, you'll need an off-the-shelf photoresistor and a pullup resistor as shown in the diagram.

Unplug the board, then wire up the photoresistor and series resistor as shown. You'll find the 3.3V and GND connections on CON710 and the A0 analog input connection on CON711; the board header map is here if you need it.

Once you reconnect your board USB cable and wait for it to get an IP address, you'll be able to wave your hand over the photoresistor and see the values change.

Publish to Subscriber

Your board is now sending 'brightness' messages to your Mosquitto broker – but no one is subscribing yet! Let's fix that, using Node-RED or MQTT.fx.

Using Node-RED as subscriber

Use this approach with your ARTIK 5/7/10 board.

  1. If not already running, start Node-RED and run it as a background process.
    node-red &

  2. Follow the MQTT Tutorial to monitor a Topic of brightness.

Using MQTT.fx as subscriber

Use this approach with your development PC. We'll assume you already configured MQTT.fx in the previous article.

  1. Start MQTT.fx and select the Subscribe tab.

  2. Enter a Topic of brightness, and click Subscribe.

Summary

You've built a stand-alone MQTT subscriber and publisher that can publish sensor data to the broker and act on messages received from the broker. You should be well equipped now to apply this simple but efficient technique to your own applications.

Last updated on: