0

I am trying to compare the string of data which I am receiving from the MQTT broker. If I receive the keyword faster I want to print "increase motor speed" and when I get slower keyword or any other keyword, I want to print "decrease motor speed". I am not sure how to store the data I receive from mqttClient.read()and then store it in string to then compare it Below is the snippet of the code where I have added it and it seems not to work correctly in my case. can you look at it and let me know what is the mistake?

while (mqttClient.available()) {
Serial.print((char)mqttClient.read());
String ipstring= String("(char)mqttClient.read()");
String fast ="faster";
if((char)mqttClient.read()==fast)
{
Serial.println("increase motor speed");}
else
{
Serial.println("decrease motor speed");
}*
}

I have also attached the code for reference. Thank you!

/*
  Azure IoT Hub NB

This sketch securely connects to an Azure IoT Hub using MQTT over NB IoT/LTE Cat M1. It uses a private key stored in the ATECC508A and a self signed public certificate for SSL/TLS authetication.

It publishes a message every 5 seconds to "devices/{deviceId}/messages/events/" topic and subscribes to messages on the "devices/{deviceId}/messages/devicebound/#" topic.

The circuit:

  • MKR NB 1500 board
  • Antenna
  • SIM card with a data plan
  • LiPo battery

The following tutorial on Arduino Project Hub can be used to setup your Azure account and the MKR board:

https://create.arduino.cc/projecthub/Arduino_Genuino/securely-connecting-an-arduino-nb-1500-to-azure-iot-hub-af6470

This example code is in the public domain. */

#include <ArduinoBearSSL.h> #include <ArduinoECCX08.h> #include <utility/ECCX08SelfSignedCert.h> #include <ArduinoMqttClient.h> #include <MKRNB.h>

#include "arduino_secrets.h" int sensorValue;

/////// Enter your sensitive data in arduino_secrets.h const char pinnumber[] = SECRET_PINNUMBER; const char broker[] = SECRET_BROKER; String deviceId = SECRET_DEVICE_ID;

NB nbAccess; GPRS gprs;

NBClient nbClient; // Used for the TCP socket connection BearSSLClient sslClient(nbClient); // Used for SSL/TLS connection, integrates with ECC508 MqttClient mqttClient(sslClient);

unsigned long lastMillis = 0;

void setup() { Serial.begin(9600); while (!Serial);

if (!ECCX08.begin()) { Serial.println("No ECCX08 present!"); while (1); }

// reconstruct the self signed cert ECCX08SelfSignedCert.beginReconstruction(0, 8); ECCX08SelfSignedCert.setCommonName(ECCX08.serialNumber()); ECCX08SelfSignedCert.endReconstruction();

// Set a callback to get the current time // used to validate the servers certificate ArduinoBearSSL.onGetTime(getTime);

// Set the ECCX08 slot to use for the private key // and the accompanying public certificate for it sslClient.setEccSlot(0, ECCX08SelfSignedCert.bytes(), ECCX08SelfSignedCert.length());

// Set the client id used for MQTT as the device id mqttClient.setId(deviceId);

// Set the username to "<broker>/<device id>/api-version=2018-06-30" and empty password String username;

username += broker; username += "/"; username += deviceId; username += "/api-version=2018-06-30";

mqttClient.setUsernamePassword(username, "");

// Set the message callback, this function is // called when the MQTTClient receives a message mqttClient.onMessage(onMessageReceived); }

void loop() { if (nbAccess.status() != NB_READY || gprs.status() != GPRS_READY) { connectNB(); }

if (!mqttClient.connected()) { // MQTT client is disconnected, connect connectMQTT(); }

// poll for new MQTT messages and send keep alives mqttClient.poll();

// publish a message roughly every 5 seconds. if (millis() - lastMillis > 5000) { lastMillis = millis();

publishMessage();

} }

unsigned long getTime() { // get the current time from the cellular module return nbAccess.getTime(); }

void connectNB() { Serial.println("Attempting to connect to the cellular network");

while ((nbAccess.begin(pinnumber) != NB_READY) || (gprs.attachGPRS() != GPRS_READY)) { // failed, retry Serial.print("."); delay(1000); }

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

void connectMQTT() { Serial.print("Attempting to MQTT broker: "); Serial.print(broker); Serial.println(" ");

while (!mqttClient.connect(broker, 8883)) { // failed, retry Serial.print("."); Serial.println(mqttClient.connectError()); delay(5000); } Serial.println();

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

// subscribe to a topic mqttClient.subscribe("devices/" + deviceId + "/messages/devicebound/#"); }

void publishMessage() { Serial.println("Publishing message");

// send message, the Print interface can be used to set the message contents mqttClient.beginMessage("devices/" + deviceId + "/messages/events/"); mqttClient.print("hello "); sensorValue = analogRead(A0); mqttClient.println(sensorValue); //mqttClient.print(millis());

mqttClient.endMessage(); }

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

// use the Stream interface to print the contents while (mqttClient.available()) { Serial.print((char)mqttClient.read()); String ipstring= String("(char)mqttClient.read()"); String fast ="faster"; if((char)mqttClient.read()==fast) { Serial.println("increase motor speed");} else { Serial.println("decrease motor speed"); } } Serial.println();

Serial.println(); }

Dave
  • 69
  • 7

1 Answers1

1

As I read the comments, I see the project requirements are evolving. The 0 = Off command structure will severely limit what you can do, but it is a good starting point.

Regarding the first block of code starting with while (mqttClient.available()) {, then adding your one digit / char commands idea, I have this test sketch for you to try.

You don't need the String object to accomplish your goal. You may have to do something like this though input = (char)mqttClient.read() where the test sketch uses this input = Serial.read();.

char input;

void setup(){ Serial.begin(9600); }

void loop(){

if(Serial.available() > 0){

input = Serial.read();

if(input == '0'){
  Serial.println(&quot;Turn Off&quot;);
}

else if(input == '1'){
  Serial.println(&quot;Turn On&quot;);
}

else if(input == '2'){
  Serial.println(&quot;Decrease Speed&quot;);
}

else if(input == '3'){
  Serial.println(&quot;Increase Speed&quot;);
}

} }

To take it a step further, let's say you want to send commands that start with a single letter, then after the letter, the remaining digits, or chars have a purpose, if you want them to. For example, lets say you send the following command d50. The d could mean decrease speed, and the 50 could mean 50%, 50 steps, etc.

The following test sketch illustrates my point.

char inputBuffer[64 + 1];

void setup(){ Serial.begin(9600); }

void loop(){

while(Serial.available() > 0){

Serial.readBytesUntil('\n', inputBuffer, sizeof(inputBuffer));

if(inputBuffer[0] == 'f'){
  Serial.println(&quot;Letter 'f' entered&quot;);
}

// Letter &quot;r&quot;. Everything after the &quot;r&quot; should be digits.
else if(inputBuffer[0] == 'r'){
  Serial.print(&quot;Letter 'r' entered\t&quot;);
  // Change the letter &quot;r&quot; to the digit 0 to keep atol() happy.
  inputBuffer[0] = B110000;
  Serial.print(&quot;Number entered = &quot;);
  Serial.println(atol(inputBuffer));

  // Your code here that uses the number parsed using atol().

}

// Letter &quot;s&quot;. Everything after the &quot;s&quot; should have a max
// length of up to 64 chars long for a 64 + 1 char buffer.
else if(inputBuffer[0] == 's'){

  // MAX CHARS example with a 64 byte buffer:
  // s123456789a123456789b123456789c123456789d123456789e123456789f + CR + NL
  Serial.print(&quot;Letter 's' entered\tText entered = &quot;);

  // Print out the chars in the buffer.
  for(int i = 1; i &lt; strlen(inputBuffer); i++){
    Serial.print(inputBuffer[i]);
  }
  Serial.println();

  // Your code here that uses the char data after the letter &quot;s&quot; is entered.

}
memset(inputBuffer, 0, sizeof(inputBuffer));

} }

VE7JRO
  • 2,554
  • 18
  • 25
  • 29