Using Serial.read() with const char * in Arduino RadioHead - c++

I'm trying to send text over the serial monitor using RadioHead ASK. Text input from the serial monitor is not sent to the receiver. I have read up on C++ theory with char arrays and pointers... it's not computing in my head :). How can *msg exist without first declaring char msg? Please see the sample below. It would be great if you could explain the theory with any sample solution. Thank you for your help!
void setup() {
Serial.begin(9600); // Debugging only
if (!driver.init())
Serial.println("init failed");
else
Serial.println("TX");
}
void loop() {
const char *msg = Serial.read();
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
delay(200);
}

This seems to work. strMsg.toCharArray(msg, i); Can you please comment on the efficiency of the code? Is there a better way? Thanks!
void setup() {
Serial.begin(9600); // Debugging only
if (!driver.init())
Serial.println("init failed");
else
Serial.println("TX");
}
void loop() {
if (Serial.available() > 0)
{
String strMsg = "";
int i;
strMsg = Serial.readString();
i = (strMsg.length() + 1);
char msg[i] = {};
Serial.print("Sent: ");
Serial.println(strMsg);
Serial.print("Size: ");
Serial.println(i);
strMsg.toCharArray(msg, i);
driver.send((uint8_t *)msg, strlen(msg));
driver.waitPacketSent();
delay(200);
}
}

Related

Arduino communication via COM Port isnt working

I want my Arduino to light up the LED if he reads "on" in the Serial Port.
At Serial.print(serialData); it prints out what he reads but at if (serialData == "on") it wont work.
int led1 = 9;
int led2 = 6;
String serialData;
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
Serial.begin(9600);
Serial.setTimeout(10);
}
void loop() {
if (Serial.available() > 0){
serialData = Serial.readString();
Serial.print(serialData);
if (serialData == "on"){
analogWrite(led1, 255);
}
if (serialData == "off"){
analogWrite(led1, 0);
}
}
}
Anybody know, what I'm doing wrong?
There are two issues in your code:
The timeout is set to 10ms. In 10ms, you can at best enter a single character. readString() will return after a single character and the read string will likely be "o", "n", "f".
When you hit the RETURN key, a carriage return and a line feed character are also transmitted ("\r\n").
The solution is to increase the timeout considerably and to use readStringUntil() to read until the newline character is discovered. This is the indication that a full word (or command) has been entered.
Additionally, the carriage return and line feed need to be trimmed off.
#include <Arduino.h>
int led1 = 9;
int led2 = 6;
String serialData;
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
Serial.begin(9600);
Serial.setTimeout(2000);
}
void loop() {
if (Serial.available() > 0){
serialData = Serial.readStringUntil('\n');
serialData.trim();
Serial.println(serialData);
if (serialData == "on"){
analogWrite(led1, 255);
}
if (serialData == "off"){
analogWrite(led1, 0);
}
}
}

arduino on / off NON momentary switch implementation assistance

I am new to programming and Arduino.
Board - ESP8266 Nodemcu pinout as below,
What I am trying to achieve is send a command based LOW/HIGH value from pin 0.
A two leg switch's one leg is connected to D3 (GPIO0 and in program 0) and other to ground.
The code I am trying is below,
#include<BitsAndDroidsFlightConnector.h>
BitsAndDroidsFlightConnector connector = BitsAndDroidsFlightConnector();
const byte exampleButtonA = 0;
void setup() {
Serial.begin(115200);
pinMode(exampleButtonA, INPUT_PULLUP);
}
void loop() {
byte exampleButtonAvalue = digitalRead(exampleButtonA);
switch(exampleButtonAvalue)
{
case LOW:
Serial.println("ON IT IS");
break;
case HIGH:
Serial.println("OFF IT IS");
break;
default:
Serial.println("error!");
break;
}
}
Issue I am facing is, when I flash this program, Based on physical switch on or off
It continually prints either "ON IT IS" or "OFF IT IS"
The break is really not happening. I only want it to execute once.
I also tried this with if else and face same problem of repeated printing.
#include<BitsAndDroidsFlightConnector.h>
BitsAndDroidsFlightConnector connector = BitsAndDroidsFlightConnector();
const byte exampleButtonA = 0;
void setup() {
Serial.begin(115200);
pinMode(exampleButtonA, INPUT_PULLUP);
}
void loop() {
if(digitalRead(exampleButtonA) == LOW){
Serial.println("ON");
delay(200);
}
else {
Serial.println("OFF");
delay(200);
}
}
Any assistance?
If you want to see message only once you need to write youre code in setup() section.
All code in loop() section is repeated in loop.
Replace you code with this:
#include<BitsAndDroidsFlightConnector.h>
BitsAndDroidsFlightConnector connector = BitsAndDroidsFlightConnector();
const byte exampleButtonA = 0;
int exampleButtonAvalue = 0;
int saved_exampleButtonAvalue = 0;
void setup() {
Serial.begin(115200);
pinMode(exampleButtonA, INPUT_PULLUP);
}
void loop() {
exampleButtonAvalue = digitalRead(exampleButtonA);
if (exampleButtonAvalue != saved_exampleButtonAvalue){
if(exampleButtonAvalue == LOW){
Serial.println("ON");
} else {
Serial.println("OFF");
}
saved_exampleButtonAvalue = exampleButtonAvalue;
}
delay(200);
}

Why Wemos D1 not respond after working for a while

I’m trying to build a feeder machine on a pig farm by using the Infrared photoelectric switch Sensor E18-D80NK to control relay then send notifications to line and mqtt broker when it’s working. I have been testing for 2 days, it’s working normal, but third day, it’s not responding then I just press reset so it’s working again.
I’m wondering it may cause by board cause it happen only one of four boards that I tasted or may be my code cause I was confused why output to line send “connected” so many times it’s should sent only one time when connected to wifi, so I’m not sure pls help.
Question
Why board not responding after working normal for a while.
Why out output to line send "connected" more than one cause I put in void setup()
Pictures
Last line output since working
All code
extra library line notification library
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <TridentTD_LineNotify.h>
const char* ssid = "Artnaseaw-2.4G";
const char* password = "0812667120";
const char* mqttUser = "****";
const char* mqttPassword = "****";
const char* mqttServer = "******";
const int mqttPort = *****;
const char* linetoken = "********";
long lastMsg = 0;
String DataString;
int lastL=0;
WiFiClient espClient;
PubSubClient client(espClient);
const int ACTION = D8;
const int SENSOR = D2;
const char* host = "maker.ifttt.com";
const char *privateKey = "******";
const char *event = "*****";
String value1, value2;
String postData = "";
String MachineID="A01";
void setup() {
Serial.begin(115200);
pinMode(SENSOR, INPUT_PULLUP);
pinMode(ACTION, OUTPUT);
digitalWrite(SENSOR, LOW);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
if (client.connect("test", mqttUser, mqttPassword )) {
Serial.println("connected");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
client.subscribe("command");
LINE.setToken(linetoken);
LINE.notify("Connected");
Serial.println("line send connected");
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
Serial.println("-----------------------");
}
void loop() {
client.loop();
delay(5000);
int sensorValue = digitalRead(SENSOR);
long now = millis();
if (now - lastMsg > 60000)
{
lastMsg = now;
int sensorValue = digitalRead(SENSOR);
if (sensorValue == LOW){
Serial.println(" === Obstacle detected");
Serial.print(" realy OFF ");
digitalWrite(ACTION,LOW);
} else {
LINE.notify("send data to line ---working");
Serial.println(" === All Clear");
Serial.println(" relay ON ");
digitalWrite(ACTION,HIGH);
sendMessageToIFTTT();
sendSensorToMQTT();
}
}
}
void sendSensorToMQTT(){
char msg[100];
int count = 1;
DataString = "e18,location=test detest="+String(count);
DataString.toCharArray(msg, 100);
Serial.print("Publish message: ");
Serial.println(msg);
client.publish("e18", msg);
}
void sendMessageToIFTTT(){
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
String url = "/trigger/";
url += event;
url += "/with/key/";
url += privateKey;
value1 = "Worked";
value2 = "1";
genJSonObject();
Serial.print("Requesting URL: ");
Serial.println(url);
Serial.println(postData);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n");
client.println("Content-Type: application/json");
client.print("Content-Length: ");
client.println(postData.length());
client.println();
client.println(postData);
client.println("Connection: close\r\n\r\n");
while (client.connected())
{
if (client.available())
{
String line = client.readStringUntil('\r');
Serial.print(line);
} else {
// No data yet, wait a bit
delay(50);
};
}
}
void genJSonObject()
{
postData = "{";
postData.concat("\"value1\":\"");
postData.concat(value1);
postData.concat("\",");
postData.concat("\"value2\":\"");
postData.concat(value2);
postData.concat("\"}");
}
Try to connect to another mqtt broker and see if it connects more than once in there too. If it happens the problem might be in the sketch. Otherwise, the cause may be with the IFTTT service.

MQTT client not subscribing to a given topic (or callback not working as intended)

I'm going nuts trying to guess why my Arduino Nano33 is not being able to receive mqtt messages. Or may be it receives them but the callback function is not working as I intend (since the callback is the only way I have to see if a message was received).
I can publish messages without problem. Any clues on what can be wrong in my code? (I have zero experience with C++ so it could be some stupid mistake).
I'm copying the entire code in case the issue is somewhere else, but I guess the key functions to look at are callback and setup.
#include <WiFiNINA.h>
#include <PubSubClient.h>
#include <Arduino_LSM6DS3.h>
#include "credentials.h"
const char* ssid = SSID_WIFI;
const char* password = PW_WIFI;
const char* mqttServer = MQTT_SERVER;
const int mqttPort = MQTT_PORT;
const char* mqttUsername = MQTT_USRNM;
const char* mqttPassword = MQTT_PW;
char pubTopic[] = "sensors/imu1/values";
char subTopic[] = "sensors/imu1/mode";
WiFiSSLClient wifiClient; //SSL
PubSubClient client(wifiClient);
void setup_wifi()
//Connect to wifi network
{
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
//char* payload_chr;
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
//payload_chr[i] = (char)payload[i];
Serial.print((char)payload[i]);
}
Serial.println();
//String message = payload_chr;
//Serial.print(message);
}
void reconnect()
{
// Loop until we're reconnected
while (!client.connected())
{
Serial.print("Attempting MQTT connection...");
String clientId = "Nano33-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str(), mqttUsername, mqttPassword))
{
Serial.println("connected");
// ... and resubscribe
client.subscribe(subTopic);
} else
{
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup()
{
Serial.begin(9600);
setup_wifi();
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}
Serial.println("IMU initialized!");
}
void publish_imu_values(float x_acc, float y_acc, float z_acc,
float x_gyr, float y_gyr, float z_gyr){
//Publish imu readings in InfluxDB Line Protocol format
String temp_str;
char mensaje[100];
temp_str = "imu x_acc=";
temp_str += String(x_acc);
temp_str += ",y_acc=";
temp_str += String(y_acc);
temp_str += ",z_acc=";
temp_str += String(z_acc);
temp_str += ",x_gyr=";
temp_str += String(x_gyr);
temp_str += ",y_gyr=";
temp_str += String(y_gyr);
temp_str += ",z_gyr=";
temp_str += String(z_gyr);
temp_str.toCharArray(mensaje, temp_str.length() + 1);
client.publish(pubTopic, mensaje);
}
void loop()
{
if (!client.connected())
{
reconnect();
}
float x_acc, y_acc, z_acc;
float x_gyr, y_gyr, z_gyr;
if (IMU.accelerationAvailable() && IMU.gyroscopeAvailable()) {
IMU.readAcceleration(x_acc, y_acc, z_acc);
IMU.readGyroscope(x_gyr, y_gyr, z_gyr);
publish_imu_values(x_acc, y_acc, z_acc, x_gyr, y_gyr, z_gyr);
}
delay(1000);
}
You need a client.loop(); line in your loop() main function. Without that line, you MQTT code never gets executed.

How to send/receive via UDP with ESP8266-12E

Well I've already done UDP send/receive many times. But now I'm stucked.
Maybe I'm missing some dumb mistake that's in the code or maybe there's problem in the libraries that I'm using. Anyway if there's someone who could help please take a look.
Code of the receiver
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char* ssid = "M3-L7";
const char* password = "mySmartChoice";
unsigned int localPort = 2390;
char packetBuffer[255];
WiFiUDP Udp;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Udp.begin(localPort);
}
void loop() {
delay(10);
if (Udp.parsePacket()) {
int len = Udp.read(packetBuffer, 255);
if (len > 0) {
packetBuffer[len] = 0;
Serial.println(packetBuffer);
}
}
}
The code of the sender/accesss point
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char *ssid = "M3-L7";
const char *password = "mySmartChoice";
unsigned int localPort = 2390;
WiFiUDP Udp;
void setup() {
delay(1000);
Serial.begin(115200);
WiFi.softAP(ssid, password);
Udp.begin(localPort);
}
void loop() {
Udp.beginPacket("192.168.4.1", localPort);
Udp.write("Hello");
Udp.endPacket();
delay(10);
}
Well I'd expect "Hello" to be printed repeatedly :D.. they reach the point where they connect but that's over.
You might want to try adding the following to your receiver just before Wifi.begin:
WiFi.mode(WIFI_STA);
This sets the Wifi up as a station (client) rather than an access point. Your code isn't doing this so it's difficult to be certain what is going on, especially if you are re-using a device that was previously programmed to run in AP mode.