1

I am trying to determine why my Arduino MKR NB 1500 code keeps crashing when the serial monitor is open and I look for data. I removed the string functions to prevent it from causing memory fragmentation, but does not seems to have helped.

#include <ArduinoMqttClient.h>
#include <MKRNB.h>

// Please enter your sensitive data in the Secret tab or arduino_secrets.h
// PIN Number
const char PINNUMBER[]     = "";

// MQTT Broker and Port
const char broker[] = "test.mosquitto.org"; //
int        port     = 1883;

// Pub/Sub Topics - Make it something unique since we are using a public broker
const char subscribeTopic[]  = "channel";
const char publishTopic[]  = "channel";

// To connect with SSL/TLS:
// 1) Change NBClient to NBSSLClient.
// 2) Change port value from 1883 to 8883.
// 3) Change broker value to a server with a known SSL/TLS root certificate 
//    flashed in the WiFi module.

NBClient client;
GPRS gprs;
NB nbAccess;
MqttClient mqttClient(client);

int LED = 6; // Onboard LED

// Publish interval
long previousMillis = 0; 
long interval = 2000;

void setup() {
    pinMode(LED_BUILTIN, OUTPUT); // Set built in LED pinMode
  
    //Initialize serial and wait for port to open:
    Serial.begin(9600);
    /* while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
    }*/

    // attempt to connect to GSM and GPRS:
    Serial.print("Attempting to connect to GSM and GPRS");
    // connection state
    bool connected = false;

    // After starting the modem with GSM.begin()
    // attach the shield to the GPRS network with the APN, login and password
    while (!connected) {
        if ((nbAccess.begin(PINNUMBER) == NB_READY) &&
                (gprs.attachGPRS() == GPRS_READY)) {
            connected = true;
        } else {
            Serial.println("Not connected");
            delay(1000);
        }
    }

    Serial.println("You're connected to the network");
    Serial.println();

    Serial.print("Attempting to connect to the MQTT broker: ");
    Serial.println(broker);

    if (!mqttClient.connect(broker, port)) {
        Serial.print("MQTT connection failed! Error code = ");
        Serial.println(mqttClient.connectError());

        while (1)
            ;
    }

    Serial.println("You're connected to the MQTT broker!");
    Serial.println();

    // set the message receive callback
    mqttClient.onMessage(onMqttMessage);

    Serial.print("Subscribing to topic: ");
    Serial.println(subscribeTopic);
    Serial.println();

    // subscribe to a topic
    mqttClient.subscribe(subscribeTopic);

    Serial.print("Waiting for messages on topic: ");
    Serial.println(subscribeTopic);
    Serial.println();
}

void loop() {
    unsigned long currentMillis = millis(); 
  
    // call poll() regularly to allow the library to receive MQTT messages and
    // send MQTT keep alives which avoids being disconnected by the broker
    mqttClient.poll();

    // Enforce Interval
    if (currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;

        // Call a function that handles publishing message
        publishSensorVal();
    }
}

void publishSensorVal() {
    // read the first Analog pin
    int sensorVal = analogRead(0);     
    //String speak = "The sensor val is " + String(sensorVal);
    char adc_sv[30] = { 'T', 'h', 'e', ' ', 'a', 'd', 'c', ' '' ', 'v', 'a', 'l', 'u', 'e', ' ', 'i', 's', ' ', '\0' }; //adc_step value
    // Publish our sensor value to the publish topic
    mqttClient.beginMessage(publishTopic);
    mqttClient.print(adc_sv);
    mqttClient.print(sensorVal);
    mqttClient.endMessage();
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(1400);                       // wait for a second
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    delay(100);                       // wait for a second
}

void handleCommand(String cmd) {
    if (cmd == "on") {
        digitalWrite(LED, HIGH);
    } else if (cmd == "off") {
        digitalWrite(LED, LOW);
    }
}

void onMqttMessage(int messageSize) {
    // we received a message, print out the topic and contents
    Serial.println("Received a message with topic '");
    Serial.print(mqttClient.messageTopic());
    Serial.print("', length ");
    Serial.print(messageSize);
    Serial.println(" bytes:");

    // We want to read each character into a useable String
    String content = "";
    char character;
  
    // use the Stream interface to print the contents
    while (mqttClient.available()) {
        character = (char)mqttClient.read();
        content.concat(character);
    }

    handleCommand(content); // This function does something with our incoming string

    Serial.println(content);
    Serial.println();
    Serial.println(); // double spacing
}

The output looks as follows when it gets stuck:enter image description here

Dave
  • 69
  • 7
  • I still have memory left on the arduino which should not be the reason for the crash: Sketch uses 41676 bytes (15%) of program storage space. Maximum is 262144 bytes. Global variables use 3456 bytes (10%) of dynamic memory, leaving 29312 bytes for local variables. Maximum is 32768 bytes. – Dave Sep 28 '21 at 19:57
  • how do you know it crashes? – Juraj Sep 28 '21 at 20:01
  • it stops printing data in the serial monitor. I reopened the serial monitor even after that there was no info on it. I reset it fixes the issue. – Dave Sep 28 '21 at 20:41
  • 2
    Where exactly does it stop printing? In the middle of a message? Or inbetween messages? Btw: For defining `adc_sv` you don't need to set each character like an array element. `char adc_sv[30] = "The adc value is ";` does exactly the same and is easier to understand. – chrisl Sep 28 '21 at 20:54
  • If it stops sending on the serial line, does it still blink the LED? – the busybee Sep 29 '21 at 09:29
  • The devices prints complete message and then stops. Have never seen where it stopped in between printing a message on the serial monitor – Dave Sep 29 '21 at 13:45
  • 1
    Change the `while (mqttClient.available())` loop where it using `String.concat()` function, it is likely causing heap fragmentation. – hcheung Sep 29 '21 at 14:25
  • @hcheung: I am trying to send 0 to turn off the LED and 1 to turn on the LED and I modified the section to get the data in just char and the handle command to accept char but that leads to the error: ISO C++ forbids comparison between pointer and integer [-fpermissive]. – Dave Sep 29 '21 at 17:08
  • here is the modified snippet: char character; // use the Stream interface to print the contents while (mqttClient.available()) { character = (char)mqttClient.read(); //content.concat(character); } handleCommand(character) – Dave Sep 29 '21 at 17:08
  • void handleCommand(char cmd) { if (cmd == "1"){ digitalWrite(LED, HIGH); }else if(cmd == "0"){ digitalWrite(LED, LOW); } } – Dave Sep 29 '21 at 17:08
  • 1
    For comparison of a char, it should be `cmd='1'`, notice the difference between single quote and double quote? if you want to compare with an array or c-style string, you need to learn on how to use [ functions](https://cplusplus.com/reference/cstring/) such as 'strstr()` or `strcmp()`. – hcheung Sep 30 '21 at 00:35
  • `{ 'T', 'h', 'e', ' ', 'a', 'd', 'c', ' '' ',` You appear to have a pair of adjacent character literals in your code. So far as I know this isn't valid. So, you want to check your post for errors in pasting. – timemage Sep 30 '21 at 01:27
  • yeah i fixed that after I complied the code. – Dave Sep 30 '21 at 14:51

0 Answers0