[Solved] Move line in char array

Hi!

First of all, yes I'm a newbie. I've only has an Arduino for a couple of months and have never programmed before.
What I'm trying to do is have one Arduino send a string of text to another Arduino using two nRF24s and then display the received text on an Adafruit OLED display.
What works is: strings (or char arrays) are being sent and displayed nicely one line at a time, so I'm pretty proud of myself so far :slight_smile: But here comes the part where I'm getting it wrong and I don't understand what I'm doing wrong.
To explain a bit further: Arduino 1 sends these text strings when something happens and lets Arduino2 know of this. What I want to do is display the last two events on the display (now I'm only getting one) so that on line 1 the newest event is shown and on line 2 the previous event is shown, also I want the displayed text only to be updated when there's something new to report. So I have this:

  if (strcmp(payloadRX.Message, dispMessage[0]) != 0) {
    dispMessage[1] = dispMessage[0];
    dispMessage[0] = payloadRX.Message;
  }

which clearly does not work. payloadRX.Message is the char array that is received and dispMessage is defined as char* dispMessage[2];
dispMessage[0] does get updated with what is received, but it doesn't copy the last event to index [1], I tried strcpy too, but same results.
Knowing myself, it's something really stupid I'm overlooking but I'm totally stuck, any help would be greatly appreciated.

Mikael

Hello and welcome :slight_smile:

Edit: sorry I have misunderstood.

What if you try to replace:

if (strcmp(payloadRX.Message, dispMessage[0]) != 0) {

by:

if (strcmp(payloadRX.Message, &dispMessage[0]) != 0) {

Hi and thank you,

That gives me: cannot convert 'char**' to 'const char*' for argument '2' to 'int strcmp(const char*, const char*)'
Weird this is, that I think that the if-statement works since dispMessage[0] does get updated properly with what is received. Then again without the if-statement dispMessage[1] = dispMessage[0]; seems to work as I get the same text on both lines.
I'm confused.

Mikael

I tried strcpy too, but same results.

You can't copy to a pointer, unless that pointer points to something. It sounds like you have a ways to go in understanding just what pointers are (specifically, the difference between a pointer that points to static space and pointer that points to dynamic memory or initialized and uninitialized pointers).

If you always know where the pointer is pointing, and that where the pointer points is meaningful, you will not have problems with pointers. Using a pointer as an alternative to an array does NOT work, if the pointer has not been made to point to an array.

Yes sorry for that error :blush:

This works: C++ code - 23 lines - codepad

PaulS:

I tried strcpy too, but same results.

You can't copy to a pointer, unless that pointer points to something. It sounds like you have a ways to go in understanding just what pointers are (specifically, the difference between a pointer that points to static space and pointer that points to dynamic memory or initialized and uninitialized pointers).

If you always know where the pointer is pointing, and that where the pointer points is meaningful, you will not have problems with pointers. Using a pointer as an alternative to an array does NOT work, if the pointer has not been made to point to an array.

That's some heavy use of the word point and derivatives thereof :smiley: But I do agree, I'm clueless when it comes to what's pointing where and why in Arduino. I'm good at pointing with my fingers though.

I'm good at pointing with my fingers though.

Same concept, really. You have to be pointing to something if that something is to be used as the destination of a copy operation, and the thing you are pointing to must be big enough.

I just don't get it, got it as far as moving the text one time at startup, but then it just refreshes the newest entry without moving the previous data to the other line. Maybe I'll just display the latest status, at least that was easy :slight_smile:

Thanks for your help!

I'm clueless when it comes to what's pointing where and why in Arduino

While not specific to the Arduino or C, this might help you get a grasp of what pointers are all about, especially the section towards the end of the article:

I just don't get it, got it as far as moving the text one time at startup, but then it just refreshes the newest entry without moving the previous data to the other line. Maybe I'll just display the latest status, at least that was easy

Likely what is happening is that all of your pointers point to the same thing. When you copy a pointer that points to your house, it still points to your house. Point the pointer at something else, and both copies point to the new thing (string).

We need to see all of your code.

Thank you so much for taking the time to look into this! My code is:

#include <SPI.h>
#include <LedControlSPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <nRF24L01.h>
#include <RF24.h>
//#include <printf.h>

RF24 radio(9,10);
Adafruit_SSD1306 display(5, 7, 6);
LedControl lc1=LedControl(8, 1); 
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
char* dispMessage[2]; // array to hold messages to display
float voltage; // Transmitter battery voltage
boolean newDataReceived = false;

// nRF24 receiving payload
struct payload_r {
  float RXv; // Receiver battery voltage
  char Message[18]; // Last action
};
payload_r payloadRX;

void setup() {
//  Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
  // Initialize MAX7221
  lc1.shutdown(0,false);
  lc1.setIntensity(0,15);
  // Initialize display
  display.begin(SSD1306_SWITCHCAPVCC);
  display.display();
  delay(500);
  // Initialize radio
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.setPayloadSize(22);
  radio.openWritingPipe(pipes[1]);
  radio.openReadingPipe(1,pipes[0]);
  radio.startListening();
  // And we're ready
  display.clearDisplay();
  dispMessage[0] = "Transmitter ready";
}
void loop() {
  if (radio.available()) {
    boolean done = false;
    while (!done) {
      // Fetch the payload, and see if this was the last one.
      done = radio.read(&payloadRX, sizeof(payloadRX));
    }
  }
  if (strcmp(payloadRX.Message, dispMessage[0]) != 0) {
    newDataReceived = true;
  }
  if (newDataReceived == true) {
    dispMessage[1] = dispMessage[0];
    dispMessage[0] = payloadRX.Message;
    newDataReceived = false;
  }
  ledArc(5, analogRead(A2)); // Right arc
  ledArc(2, analogRead(A3)); // Left arc
  ReceiverVoltage(); // Read receiver voltage
  UpdateDisplay();
}

I've changed it quite a bit since my first posting, but that's what I'm trying now. All the called functions work, radio is read and the display gets updated and so on, but I just can't get the received messages to behave as I want.

econjack:
While not specific to the Arduino or C, this might help you get a grasp of what pointers are all about, especially the section towards the end of the article:

Computer Programming and Precise Terminology | Dr Dobb's

Thank you for the link, very interesting and clarifying reading!

Mikael

I expect the issue is that you're copying the pointers and not the actual string.
If you define your dispmessages as strings or character arrays instead of character pointers, maybe it will do what you want.
The thing is, you can't copy strings with simple assignment operators in C. You have to copy the actual characters explicitly. Use strcpy().

// untested code

char dispMessage[2][18] = {"Transmitter Ready", ""};

...

  if (strcmp(payloadRX.Message, dispMessage[0]) != 0) {
    newDataReceived = true;
  }
  if (newDataReceived == true) {
    strcpy(dispMessage[1], dispMessage[0]);
    strcpy(dispMessage[0], payloadRX.Message);
    newDataReceived = false;
  }

That works perfectly! Thank you so much!

Mikael