Hi! I have two arduino UNO connected to UART (RX-TX / TX-RX). I want to send text messages, for example, "LED on" or "LED off" via UART. I wrote the following code that does not want to work:
You can't use SoftwareSerial reliably at such high baud rates. You should avoid it altogether, as it's a complete waste of resources, especially since you have other options for inter-UNO communication, such as SPI and I²C.
In my opinion, you shouldn't use the ESP8266 like that.
For serious projects, you shouldn't use AT commands, but program the ESP directly.
Even when programming the ESP8266 directly, the Arduino UNO is not a good choice for adding extra IO. In that case, you'll be much better off using a IO extender, multiplexer, shift register or external ADC. These devices are well supported and much easier to use than to write your own Serial protocol for turning the Arduino UNO into a smart IO extender.
You'll get much better recommendations if you post some more details about your project.
Do you have an ESP8266 dev board (with USB interface), or one of those ESP-01 boards?
I have an ESP8266 NodeMCU. The fact is that in my DIY device there is a separate board, which I developed in EAGLE, on this board there is Atmega328P (which is used by Arduino UNO). On this board everything is already collected, and I do not have the opportunity to transfer everything to
board ESP8266. Before that, I planned to connect my board to ESP using I2C, because the board had logic 5v and ESP 3.3V - I ordered a level converter on eBay, but unfortunately the terminal was lost by mail and I do not have time to order a new. Therefore, I also decided to connect to the UART via a voltage divider so that the ESP does not fail.
Do you think this is a good solution? It works, but I'm not sure of the correctness.
int const LED = 13;
// Serial Input Variables
int intLoopCounter = 0;
String strSerialInput = "";
// the setup routine runs once when you press reset:
void setup()
{
pinMode(LED, OUTPUT);
Serial.begin(115200);
}
void loop()
{
// Slow down a bit.
// Note: This may have to be increased for longer strings or increase the iteration in GetPossibleSerialData() function.
delay(1);
CheckAndExecuteSerialCommand();
}
void CheckAndExecuteSerialCommand()
{
//Get Data from Serial
String serialData = GetPossibleSerialData();
if (serialData.startsWith("Led.On"))
{
digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level)
}
else if (serialData.startsWith("Led.Off"))
{
digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW
}
}
String GetPossibleSerialData()
{
String retVal;
int iteration = 10; // 10 times the time it takes to do the main loop
if (strSerialInput.length() > 0)
{
// Print the retreived string after looping 10(iteration) ex times
if (intLoopCounter > strSerialInput.length() + iteration)
{
retVal = strSerialInput;
strSerialInput = "";
intLoopCounter = 0;
}
intLoopCounter++;
}
return retVal;
}
void serialEvent()
{
while (Serial.available())
{
strSerialInput.concat((char) Serial.read());
}
}
On my board there is a MOSFET that controls the 12V load, there is an RTC to which the supercapacitor is connected, there is AMS 3.3V for ESP power supply and contacts for connecting buttons and sensors.
No. Don't use String. Use C strings (null terminated char array). String wastes memory and can lead to unreliable operation due to memory fragmentation.
PieterP, thanks! I learned a lot from this topic! I chose example number 5, changed the code slightly and it works fine! I sent several messages: "<Hello World!>" / "<24y>" / "" / "", all of them were successfully delivered and displayed on the port monitor.
// Example 5 - Receive with start- and end-markers combined with parsing
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
// variables to hold the parsed data
char messageFromPC[numChars] = {0};
int integerFromPC = 0;
float floatFromPC = 0.0;
boolean newData = false;
//============
void setup() {
pinMode(13, OUTPUT);
Serial.begin(9600);
Serial.println("This demo expects 3 pieces of data - text, an integer and a floating point value");
Serial.println("Enter data in this style <HelloWorld, 12, 24.7> ");
Serial.println();
}
//============
void loop() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
showParsedData();
newData = false;
}
}
//============
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars,","); // get the first part - the string
strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
integerFromPC = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
floatFromPC = atof(strtokIndx); // convert this part to a float
}
//============
void showParsedData() {
Serial.print("Message ");
Serial.println(messageFromPC);
if(messageFromPC == "24y") {
digitalWrite(13, HIGH);
}
if(messageFromPC == "HelloWorld!") {
digitalWrite(13, HIGH);
}
//Serial.print("Integer ");
//Serial.println(integerFromPC);
//Serial.print("Float ");
//Serial.println(floatFromPC);
}
Now I'm trying to put a message in the condition. The output of messages to the monitor port is as follows: