1

Topic: Edit Field Bazaar Consequences

Hi all,

Just trying something really basic, which is sending a char string to the Arduino and then displaying it within serial monitor. My code is at the end of this message.

As a check, the code includes the basic LED operators, which all work fine when no text is sent.

When I send the text, nothing appears in the serial monitor and further more, both LEDs illuminate. It cant be down to the string being sent exceeding the field length, as that is set to 51 and this happens if I simply send a 'Y'

--------------------------------------------------------------------

//////////////////////////////////////////////
//        RemoteXY include library          //
//////////////////////////////////////////////

// RemoteXY select connection mode and include library
#define REMOTEXY_MODE__ESP8266_SOFTSERIAL_POINT
#include <SoftwareSerial.h>

#include <RemoteXY.h>

// RemoteXY connection settings
#define REMOTEXY_SERIAL_RX 2
#define REMOTEXY_SERIAL_TX 3
#define REMOTEXY_SERIAL_SPEED 19200
#define REMOTEXY_WIFI_SSID "RemoteXY"
#define REMOTEXY_WIFI_PASSWORD "123456789"
#define REMOTEXY_SERVER_PORT 6377


// RemoteXY configurate 
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
  { 255,53,0,52,0,49,0,10,5,1,
  2,0,32,15,22,11,2,26,31,31,
  79,78,0,79,70,70,0,1,0,37,
  35,12,12,2,31,88,0,7,36,34,
  56,20,5,2,26,2,51,67,4,33,
  66,20,5,2,26,52 };
 
// this structure defines all the variables and events of your control interface
struct {

    // input variables
  uint8_t Blue_LED; // =1 if switch ON and =0 if OFF
  uint8_t button_1; // =1 if button pressed, else =0
  char Text_2[51];  // string UTF8 end zero 

    // output variables
  char Text_1[52];  // string UTF8 end zero

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////

#define PIN_BLUE_LED 13
#define PIN_BUTTON_1 12

char receivedMsg;                         // New variable for received text.
 
void setup()
{
  RemoteXY_Init ();
  Serial.begin(9600);
  pinMode (PIN_BLUE_LED, OUTPUT);
  pinMode (PIN_BUTTON_1, OUTPUT);
 
  // TODO you setup code

} // Close Setup.

void loop()
{
  RemoteXY_Handler ();
 
  digitalWrite(PIN_BLUE_LED, (RemoteXY.Blue_LED==0)?LOW:HIGH);
  digitalWrite(PIN_BUTTON_1, (RemoteXY.button_1==0)?LOW:HIGH);
 
  // TODO you loop code
  // use the RemoteXY structure for data transfer
  // do not call delay()

  strcpy (receivedMsg, RemoteXY.Text_2);    // Copy received text from RemoteXY app to new variable.

  if (receivedMsg > "") {                   // Check if variable has data.

    Serial.print("Message Received: ");     // Print data to serial monitor.
    Serial.println(receivedMsg);

    receivedMsg = "";                       // Reset variable to blank.
   
  } // Close if.

} // Close loop

2 (edited by Guillaume 2020-07-08 12:05:50)

Re: Edit Field Bazaar Consequences

Hi,

This variable can store a single character:

char receivedMsg;

So when you do:

strcpy (receivedMsg, RemoteXY.Text_2);

You are writing to memory that you should not access.

Even if RemoteXY.Text_2 is apparently a single character 'Y', in fact it's two characters: 'Y' and '\0' which is the null terminator of the C string (it's used to indicate the end of the string), so it writes 'Y' to your char variable, and it writes '\0' to the next memory cell, which is used for something else, introducing a bug in your program so strange things (or crash) will happens.


if (receivedMsg > "")

That's not how you compare c strings


receivedMsg = "";

That's not how you reset c strings


I suggest you look tutorials how to use c strings

3

Re: Edit Field Bazaar Consequences

Hi Guillaume,

Thanks, your replies have confirmed some thoughts I was having about "char", "strings" and "Strings" with a capital S!

I will go away and do some more reading.

Regards,

Christopher

4

Re: Edit Field Bazaar Consequences

Hi,

So, answers in turn to your comments, although the app still giving funny results.


Your initial comment:

This variable can store a single character:

So I updated the char variable to be an array as follows:

char receivedMsg[51];

When you stated:

You are writing to memory that you should not access.

Even if RemoteXY.Text_2 is apparently a single character 'Y', in fact it's two characters: 'Y' and '\0' which is the null terminator of the C string (it's used to indicate the end of the string), so it writes 'Y' to your char variable, and it writes '\0' to the next memory cell, which is used for something else, introducing a bug in your program so strange things (or crash) will happens.

I understand this concept, so I have updated it to copy each array space using a for loop as follows:

  for (int i = 0; i <= 51; i++)
  {
    strcpy (receivedMsg[i], RemoteXY.Text_2[i]);    // Copy received text from RemoteXY app to new variable.
  }
  

Then you stated:

That's not how you compare c strings

So reading a variety of methods, concluded that I need to check if the arrays first position finishes with a null terminator as you stated at the beginning:

 if (receivedMsg[0] != '\0') {                     // Check if variable has data.

    Serial.print("Message Received: ");             // Print data to serial monitor.
    Serial.println(receivedMsg);

And finally, you commented:

That's not how you reset c strings

Which I have now updated to blank the array as follows:

memset(receivedMsg, 0, sizeof(51));    

Am I on the right course or should I give up and turn into a goat herder in the Himalayas?

5 (edited by Guillaume 2020-07-08 20:09:50)

Re: Edit Field Bazaar Consequences

So long as receivedMsg is big enough to contain all the characters of RemoteXY.Text_2, there is nothing wrong with this line:

strcpy (receivedMsg, RemoteXY.Text_2);

To reset a c string you can use memset like you did, but it's far more efficient to do:

receivedMsg[0] = '\0';

But, why do you need receivedMsg anyway ? Why not simply use RemoteXY.Text_2 ?

6

Re: Edit Field Bazaar Consequences

Hi,

I have made the strings the same length in the corresponding arrays, so this should be OK.

Thanks your reset command, it is far more elegant!

My project is linked to a clock I have made using Adafruit NeoPixel LED arrays and an RTC DS3221 module.

I have built into the clock lots of encouragement messages which display depending on which colour button is pressed (for my sister). However, I would like to add the ability of her sending her own messages to the LED arrays from her mobile phone. So in answer to your final question, I just find it easier to take a variable and play with it, as opposed to using the one within the RemoteXY software.

However, I am very close to abandoning using remoteXY, as I have learnt it doesn't handle interrupt requests well and the buttons on my clock and the menu system for configuring date/time/colours etc are all triggered by interrupts.

Regards,

Christopher

7

Re: Edit Field Bazaar Consequences

I have made several things using a ds3231, interrupts, buttons and remotexy, without any problem, so I don't know what you have read but maybe you are just doing something wrong

You don't need to use interrupts for buttons but even if you do that, there shouldn't be any problem if you use interrupts correctly

Show full code if you want more help