Two pieces of code work separately but not when I put them together. What am I doing wrong?

Hi,

I'm having trouble getting a DFRobot Lidar distance sensor (connected to Arduino UNO) to transmit its readings through an RF transmitter to an LCD Display (connected to an Arduino Nano).

When I code the Arduino Uno to read the distance sensor, it shows the readings fine on the serial monitor. And when I code the Arduino Uno only to send a set number to the LCD display on the Nano through the RF transmitter-receiver, that also works fine. But when I combine both pieces of codes nothing happens. No more serial monitor readings and no sending of any info to the LCD display.

Can anyone help me out? The code I used on the Uno is below. The code on the Nano should be ok.

#include"DFRobot_LIDAR07.h"
#include <Wire.h>
// Include RadioHead Amplitude Shift Keying Library
#include <RH_ASK.h>
// Include dependant SPI Library
#include <SPI.h>

// Create Amplitude Shift Keying Object
RH_ASK rf_driver;

//If using IIC mode, please enable macro USE_IIC
#define USE_IIC
#ifdef USE_IIC  
DFRobot_LIDAR07_IIC  LIDAR07;
#endif

float afstand;
char msg[6];

void setup() {

// Initialize ASK Object
  rf_driver.init();
  
  uint32_t version;
  Serial.begin(9600);

  while(!LIDAR07.begin()){
    Serial.println("The sensor returned data validation error");
    delay(1000);
  }

  version = LIDAR07.getVersion();
  Serial.print("VERSION: ");
  Serial.print((version>>24)&0xFF,HEX);
  Serial.print(".");Serial.print((version>>16)&0xFF,HEX);
  Serial.print(".");Serial.print((version>>8)&0xFF,HEX);
  Serial.print(".");Serial.println((version)&0xFF,HEX);

  //After enabling the filter, it can be stopped by calling LIDAR07.stopFilter()
  while(!LIDAR07.startFilter());

  /**
   * @brief  Configure the sensor to single acquisition mode
   * @param  mode The way data are collected
   * @n      eLidar07Single  A single collection
   * @n      eLidar07Continuous  Continuous acquisition
   * @return true (Successful) , false (Failed)
   */
  while(!LIDAR07.setMeasureMode(LIDAR07.eLidar07Single)){
      Serial.println("set measure mode err");
  
  //Open measurement (in single measurement mode, it will automatically close after sampling).To stop collection, use stopMeasure()
  LIDAR07.startMeasure();
}
}
void loop() {

   //Open measurement (in single measurement mode, it will automatically close after sampling),To stop collection, use stopMeasure()
  LIDAR07.startMeasure();
  
  //Get the collected data
  if(LIDAR07.getValue()){
    Serial.print(LIDAR07.getDistanceMM());
    afstand = LIDAR07.getDistanceMM();
  
  dtostrf (afstand, 6, 2, msg);           //converts the float into a char

  rf_driver.send((uint8_t *)msg, strlen(msg));
  rf_driver.waitPacketSent();
  delay(1000);
}
}

The setup is as follows:
Device 1:

  • Arduino Uno
  • DFRobot TOF IR Distance Sensor (SEN0413)
  • RF transmitter (433Mhz)

Device 2:

  • Arduino Nan0
  • RF receiver (433 Mhz)
  • LCD Display with I2C backpack

Thanks a lot for any help!

I am sorry, I don't understand
What are two pieces of code you try to run together?

The getDistanceMM() method returns type uint16_t. Why are you reading it into a float type?

1 Like

I think you have a problem here. You are telling the dtostrf() function you want 6 digits with 2 of them to the right of the decimal. That is 6 digits plus a decimal point plus a nul character which is a total of 8 characters. You only have msg declared with a length of 6. This means you are writing past the end of the msg buffer and corrupting other memory. The effects of memory corruption are often very strange behavior.

Correct this issue and see what happens...

What makes you think that?

Please post both sketches in full that you are trying to combine.

Chances are that:-

  1. They both use the same resources, like a pin.
  2. They use different libraries that each require access to the same resource like a timer.
  3. They each use a delay somewhere which affect the other code.

EDIT

  1. You have not got enough memory for both libraries.

And a very high chance there is memory corruption. Post #4.

Thanks for your answers. I don't have the Nano's code in hand, but will post it tomorrow.

My code is mainly based on what I have been able to find online (and not sufficiently on knowledge, I'm afraid...)

So that's the reason why I'm reading the getdistanceMM() into a float. I gather that's unnecessary ?

Also, I only actually need 4 characters to be sent through, with nothing after the decimal. So I can change the dtostrf to 4, 0, and char msg[4]?

Make it msg[5]. You need a place for the nul string terminator.

If you have an integer then there is no reason to convert it to a float. There is no fractional part anyhow.

This is the code on the receiver.

// Include RadioHead Amplitude Shift Keying Library
#include <RH_ASK.h>
// Include dependant SPI Library
#include <SPI.h>

#include <Wire.h>
#include <LiquidCrystal_I2C.h>


// Create Amplitude Shift Keying Object
RH_ASK rf_driver;

//Initialise the LCD
LiquidCrystal_I2C      lcd(0x27, 16, 2);

int i;    //and integer used to count

char msg[6];

void setup()
{
  rf_driver.init();
  Serial.begin(9600);

  lcd.init(); // Initialize the LCD
  lcd.backlight(); // Turn on the LCD backlight
  
  if (!rf_driver.init())
    Serial.println("init failed");
}

void loop()
{
  // Set buffer to size of expected message
  uint8_t buf[6];
  uint8_t buflen = sizeof(buf);

  // Check if received packet is correct size
  if (rf_driver.recv(buf, &buflen)) // Non-blocking
  {
    // Message with a good checksum received, dump it.
    Serial.print("Afstand: ");
    Serial.println((char*)buf);
    
    lcd.clear(); // Clear the screen
    lcd.print("Afstand: ");
    lcd.setCursor(2, 1);
       
    for (i = 0; i < buflen; i++)
    {
      lcd.write(buf[i]);

    }

    lcd.print((char)223);
    lcd.print(" mm");
  }
}

I changed the char msg to

char msg[5]

and changed the void loop to

void loop() {

  //Get the collected data
  if (LIDAR07.getValue()) {
    Serial.print(LIDAR07.getDistanceMM());
    dtostrf (LIDAR07.getDistanceMM(), 4, 0, msg);
  }           //converts the readout into a char

  rf_driver.send((uint8_t *)msg, strlen(msg));
  rf_driver.waitPacketSent();
  delay(1000);
}

But still no luck

For info, since I changed the msg size on the transmitter, I also changed it on the receiver:

char msg[5];

and

uint8_t buf[5];

But it didn't solve it

I tried to identify what is causing the readout sequence of the sensor to stop, by eliminating the RF related code one by one. To my amazement, the readout (Serialprint) doesn't work if any code related to the RF transmission is included. Even if I only include the loading of the library on top

// Include RadioHead Amplitude Shift Keying Library
#include <RH_ASK.h>

However, additional piece of information that might be useful: when running only the code related to the sensor (which works) I get a warning that 75% of the memory is being used. When loading the RH_ASK.h library, the warning jumps to 95% of the memory. This same warning (95%) also shows when all the RF related code is present. Could this be the reason?

Yes.

Thanks. Now, I've figured out that one can use PROGMEM to shift variables to the flash memory. But I'm a bit lost what the variables are that I want to shift?

Or have I lost the trail and should I use something else?

Well there is no large tables of values that will save you much that I can see in your code, so there is little scope for moving stuff into program memory. Note that it is only constants and not variables that you can shift into program memory.

Likewise using the F() macro on your strings doesn't save you a significant amount either because you have very little in the way of strings in your print statement.

This tells you about the macro
https://techexplorations.com/guides/arduino/programming/f-macro/

I think your only hope is to move to an Arduino that has more Static Ram in it.

Absolutely and probably is. As @Grumpy_Mike said get and Arduino with more memory. A Mega would work and you wouldn't have to change the code.

Thanks to both of you. I'll get a Mega and will revert to let you know if it worked.

Received the Mega and it works. Problem solved. Thx!

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.