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();
}
-
Comments are not for extended discussion; this conversation has been moved to chat.Juraj– Juraj ♦2021年08月19日 05:15:38 +00:00Commented Aug 19, 2021 at 5:15
1 Answer 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("Turn Off");
}
else if(input == '1'){
Serial.println("Turn On");
}
else if(input == '2'){
Serial.println("Decrease Speed");
}
else if(input == '3'){
Serial.println("Increase Speed");
}
}
}
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("Letter 'f' entered");
}
// Letter "r". Everything after the "r" should be digits.
else if(inputBuffer[0] == 'r'){
Serial.print("Letter 'r' entered\t");
// Change the letter "r" to the digit 0 to keep atol() happy.
inputBuffer[0] = B110000;
Serial.print("Number entered = ");
Serial.println(atol(inputBuffer));
// Your code here that uses the number parsed using atol().
}
// Letter "s". Everything after the "s" 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("Letter 's' entered\tText entered = ");
// Print out the chars in the buffer.
for(int i = 1; i < strlen(inputBuffer); i++){
Serial.print(inputBuffer[i]);
}
Serial.println();
// Your code here that uses the char data after the letter "s" is entered.
}
memset(inputBuffer, 0, sizeof(inputBuffer));
}
}