invalid conversion from 'const char*' to 'int'

Hi guys,

I am new to this and trying to do my best. I am setting up a remote water tank level indicator using radio links between tank and base station. (Rx). I am cutting and pasting code from radiohead and other sources to try to achieve this and am having some success. I can transmit the distance (dist) by using:
const char msg = (dist);
but when I try to convert the dist to a % of available level as per code below, I get "invalid conversion from 'const char
’ to ‘int’ [-fpermissive].

I’ve had a scout around the forum but cannot seem to understand my problem. Is anyone keen to give me a hand?

#include <RH_ASK.h>
#include <SPI.h> // Not actually used but needed to compile

RH_ASK driver;

#include <NewPing.h>
#define TRIGGER_PIN  10  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     9  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 400 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

int wae="150"; //distance in cm of sensor to water level at empty.
int waf="40"; //distance in cm from sensor to water level at full.

void setup()
{
 
    Serial.begin(9600);    
    if (!driver.init());
   
}

void loop()
{
  int dist;
  
  delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
    dist = (uS / US_ROUNDTRIP_CM);
    int percent = ((dist)/(wae)-(waf)*100);
    const char *msg = (percent);
    driver.send((uint8_t *)msg, strlen(msg));
    driver.waitPacketSent();
    delay(1000);
}

First, stop including ( ) around all your variables...

Second, if you get a error, post it all! Now you ommitted the line numbers that pointed you straight to the problem. Have a look at

int wae="150"; //distance in cm of sensor to water level at empty.
int waf="40"; //distance in cm from sensor to water level at full.

"150" is a string, not a value because of the "". Try it without. And while you're at it, change the variable names. A longer but descriptive only takes a second longer to type but is a) clearer what is does, b) easier to remember! 3 letter (or less) variables are never a good idea, certainly not as a global variable. Only very local for something like a loop counter.

Ok, thanks.

//How do you get line numbers to copy?
Here’s take 2.
Code edited to:

#include <RH_ASK.h>
#include <SPI.h> // Not actually used but needed to compile

RH_ASK driver;

#include <NewPing.h>
#define TRIGGER_PIN  10  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     9  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 400 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

int wateratempty=150; //distance in cm of sensor to water level at empty.
int wateratfull=40; //distance in cm from sensor to water level at full.

void setup()
{
 
    Serial.begin(9600);    
    if (!driver.init());
   
}

void loop()
{
  int dist;
  
  delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
    dist = (uS / US_ROUNDTRIP_CM);
    int percent = (dist/(wateratempty-wateratfull)*100);
    const char *msg = percent;
    driver.send((uint8_t *)msg, strlen(msg));
    driver.waitPacketSent();
    delay(1000);
}

Error is:

Arduino: 1.6.7 (Linux), Board: “Arduino Duemilanove or Diecimila, ATmega328”

/home/anne/Arduino/tank_level_ind_tx/tank_level_ind_tx.ino: In function ‘void loop()’:
tank_level_ind_tx:32: error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]
const char msg = percent;
^
exit status 1
invalid conversion from ‘int’ to 'const char
’ [-fpermissive]

This report would have more information with
“Show verbose output during compilation”
enabled in File > Preferences.

moose4621:
//How do you get line numbers to copy?

I think you mean to comment that line out by putting // here? :smiley: Because this time you did copy the full error including line number (32).

But next you have the precentage, this is a int, a number. Next you try to assign that to a pointer of a string (*msg), that's not going to work. Two options:

  1. Send the real number. To do this, make percentage a byte (aka a uint8_t because that's what the send expects and percentage is small enough to fit). Now call river.send(percentage, 1); This will sent it as a data package of 1 byte. Not in readable ASCII.

  2. Other option is to make a ASCII string with the info in it. This will be maximum of 4 bytes (for longest value 100), namely a '1', '0', '0' and '\0'. To do so make a message from percentage with itoa()

    int percent = (dist/(wateratempty-wateratfull)*100);
    char msg[4];
    itoa(percent, msg, 10);
    driver.send(msg, strlen(msg));

To make the longer variable names more readable it's normal to writeThemLikeThis :slight_smile:

And to fix rounding errors :wink:

    int waterRange = waterAtEmpty - waterAtFull;
    int percent = (dist * 100 + (waterRange / 2)/ waterRange);

Welcome to integer math :wink: (avoid float on a Uno)

OK, I’m learning heaps.

Now, edited as per recommendations, I get the following error:

Arduino: 1.6.7 (Linux), Board: “Arduino Duemilanove or Diecimila, ATmega328”

/home/anne/Arduino/tank_level_ind_tx_r2/tank_level_ind_tx_r2.ino: In function ‘void loop()’:
tank_level_ind_tx_r2:37: error: invalid conversion from ‘char*’ to ‘const uint8_t* {aka const unsigned char*}’ [-fpermissive]
driver.send(msg, strlen(msg));
^
In file included from /home/anne/Arduino/tank_level_ind_tx_r2/tank_level_ind_tx_r2.ino:1:0:
/home/anne/Downloads/arduino-1.6.7/libraries/RadioHead/RH_ASK.h:283:21: error: initializing argument 1 of ‘virtual bool RH_ASK::send(const uint8_t*, uint8_t)’ [-fpermissive]
virtual bool send(const uint8_t* data, uint8_t len);
^
exit status 1
invalid conversion from ‘char*’ to ‘const uint8_t* {aka const unsigned char*}’ [-fpermissive]

#include <RH_ASK.h>
#include <SPI.h> // Not actually used but needed to compile

RH_ASK driver;

#include <NewPing.h>
#define TRIGGER_PIN  10  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     9  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 400 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

int waterAtEmpty=150; //distance in cm of sensor to water level at empty.
int waterAtFull=40; //distance in cm from sensor to water level at full.

void setup()
{
 
    Serial.begin(9600);    
    if (!driver.init());
   
}

void loop()
{
  int dist;
  
  delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
    dist = (uS / US_ROUNDTRIP_CM); //raw distance in cm.
    int waterRange = waterAtEmpty - waterAtFull; //difference between full and empty in cm.
    int adjDist = dist - waterAtFull; //water level from full in cm.
    int percent = (adjDist * 100 + (waterRange / 2)/ waterRange); //water level from full expressed as %.
   // const char *msg = percent;
   char msg[4];
   itoa(percent, msg, 10);
    //driver.send((uint8_t *)msg, strlen(msg));
    driver.send(msg, strlen(msg));
    driver.waitPacketSent();
    delay(1000);
}

So, I added (uint8-t *) to line 37. It compiled, but data at Rx is 0.00 regardless of ultrasonic sensor distance.

I should also mention I am using pro mini’s at both ends so serial monitor is, well, arduous and therefore not configured. (yet).

What's the code for the receiving end?

What ARE the values of waterRange, adjDist, and percent?

septillion:
What’s the code for the receiving end?

I changed float to percent to reflect change in Tx code.

// ask_receiver.pde
// -*- mode: C++ -*-
// Simple example of how to use RadioHead to receive messages
// with a simple ASK transmitter in a very simple way.
// Implements a simplex (one-way) receiver with an Rx-B1 module

#include <RH_ASK.h>
#include <SPI.h> // Not actualy used but needed to compile

RH_ASK driver;

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);

struct dataStruct {
  float percent ;
  unsigned long counter;

} myData;


void setup()
{
  lcd.begin(16, 2);
  //Serial.begin(9600);  // Debugging only
  if (!driver.init())
    lcd.setCursor(0, 0);
  lcd.print("No comms");
}

void loop()
{
  uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
  uint8_t buflen = sizeof(buf);

  if (driver.recv(buf, &buflen)) // Non-blocking
  {
    int i;

    // Message with a good checksum received, dump it.
    driver.printBuffer("Got:", buf, buflen);
    memcpy(&myData, buf, sizeof(myData));
    //Serial.println("");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Tank Water Level: ");
    lcd.setCursor(5,1);
    lcd.print(myData.percent);
    lcd.print("%");

    //    Serial.print("  press_hg: ");
    //    Serial.print(myData.press_hg);

    //    Serial.print("  temp: ");
    //    Serial.print(myData.temp);
  //  lcd.setCursor(0, 1);
  //  lcd.print("  counter: ");
  //  lcd.print(myData.counter);
  }
}

Why put it in a weird struct? That will indeed f*ck it up... It's ASCII now, aka multiple bytes as char for each number, not the value as a single variable.

Try

    driver.printBuffer("Got:", buf, buflen);
    //Serial.println("");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Tank Water Level: ");
    lcd.setCursor(5,1);
    lcd.print(buf);
    lcd.print("%");

Or go the other way and DO sent it as a variable (aka, not use itoa() )

But also what Paul said, try to print the values of the transmitting Arduino via Serial monitor to check them.

PaulS:
What ARE the values of waterRange, adjDist, and percent?

waterRange = 110
adjDist and percent depend on signal from sonar. Currently set at about 47cm so adjDist should be 7cm and percent should therefore be approx 6.86%. (Should have thought of this earlier. I now need to invert the percentage as it currently reads % empty, not % full).

Thanks.

septillion:
Why put it in a weird struct? That will indeed f*ck it up… It’s ASCII now, aka multiple bytes as char for each number, not the value as a single variable.

Try

    driver.printBuffer("Got:", buf, buflen);

//Serial.println("");
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print(“Tank Water Level: “);
   lcd.setCursor(5,1);
   lcd.print(buf);
   lcd.print(”%”);




Or go the other way and DO sent it as a variable (aka, not use itoa() )

But also what Paul said, try to print the values of the transmitting Arduino via Serial monitor to check them.

That gives the following error:

Arduino: 1.6.7 (Linux), Board: “Arduino Duemilanove or Diecimila, ATmega328”

/home/anne/Arduino/tank_level_ind_Rx_R2/tank_level_ind_Rx_R2.ino: In function ‘void loop()’:
tank_level_ind_Rx_R2:50: error: call of overloaded ‘print(uint8_t [60])’ is ambiguous
lcd.print(buf);
^
/home/anne/Arduino/tank_level_ind_Rx_R2/tank_level_ind_Rx_R2.ino:50:18: note: candidates are:
In file included from /home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Stream.h:26:0,
from /home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/HardwareSerial.h:29,
from /home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Arduino.h:224,
from sketch/tank_level_ind_Rx_R2.ino.cpp:1:
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:59:12: note: size_t Print::print(const String&)
size_t print(const String &);
^
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:59:12: note: no known conversion for argument 1 from ‘uint8_t [60] {aka unsigned char [60]}’ to ‘const String&’
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:60:12: note: size_t Print::print(const char*)
size_t print(const char);
^
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:60:12: note: no known conversion for argument 1 from ‘uint8_t [60] {aka unsigned char [60]}’ to ‘const char*’
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:61:12: note: size_t Print::print(char)
size_t print(char);
^
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:61:12: note: no known conversion for argument 1 from ‘uint8_t [60] {aka unsigned char [60]}’ to ‘char’
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:62:12: note: size_t Print::print(unsigned char, int)
size_t print(unsigned char, int = DEC);
^
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:62:12: note: no known conversion for argument 1 from ‘uint8_t [60] {aka unsigned char [60]}’ to ‘unsigned char’
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:63:12: note: size_t Print::print(int, int)
size_t print(int, int = DEC);
^
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:63:12: note: no known conversion for argument 1 from ‘uint8_t [60] {aka unsigned char [60]}’ to ‘int’
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:64:12: note: size_t Print::print(unsigned int, int)
size_t print(unsigned int, int = DEC);
^
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:64:12: note: no known conversion for argument 1 from ‘uint8_t [60] {aka unsigned char [60]}’ to ‘unsigned int’
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:65:12: note: size_t Print::print(long int, int)
size_t print(long, int = DEC);
^
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:65:12: note: no known conversion for argument 1 from ‘uint8_t [60] {aka unsigned char [60]}’ to ‘long int’
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:66:12: note: size_t Print::print(long unsigned int, int)
size_t print(unsigned long, int = DEC);
^
/home/anne/Downloads/arduino-1.6.7/hardware/arduino/avr/cores/arduino/Print.h:66:12: note: no known conversion for argument 1 from ‘uint8_t [60] {aka unsigned char [60]}’ to ‘long unsigned int’
exit status 1
call of overloaded ‘print(uint8_t [60])’ is ambiguous

Alright alright alright, lie to the compiler and make it:

    lcd.print((char*)buf);

But did you actually print the values (via serial) of the transmitting Arduino?

OK, getting closer.

On line 2 of lcd I get a reasonable response. ie, 3700, followed by garble for the remainder of the line.

Serial monitor on Tx shows good dist, good adjdist, but percent is copy of adjdist x 100.

Update of Tx code:

#include <RH_ASK.h>
#include <SPI.h> // Not actually used but needed to compile

RH_ASK driver;

#include <NewPing.h>
#define TRIGGER_PIN  10  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     9  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 400 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

int waterAtEmpty=150; //distance in cm of sensor to water level at empty.
int waterAtFull=40; //distance in cm from sensor to water level at full.

void setup()
{
 
    Serial.begin(9600);    
    if (!driver.init());
   
}

void loop()
{
  int dist;
  
  delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
    dist = (uS / US_ROUNDTRIP_CM); //raw distance in cm.
    int waterRange = waterAtEmpty - waterAtFull; //difference between full and empty in cm.
    int adjDist = dist - waterAtFull; //water level from full in cm.
    int percent = (adjDist * 100 + (waterRange / 2)/ waterRange); //water level from full expressed as %.
   // const char *msg = percent;
   char msg[4];
   itoa(percent, msg, 10);
   //byte(percentage);
    //driver.send((uint8_t *)percent, 1);
   driver.send((uint8_t *)msg, strlen(msg));
    driver.waitPacketSent();
    delay(1000);
   
    Serial.print("dist ");
    Serial.print(dist);
    Serial.print("  adjDist ");
    Serial.print(adjDist);
    Serial.print("  Percent ");
    Serial.print(percent);
    Serial.println("");
}

Update of Rx code:

// ask_receiver.pde
// -*- mode: C++ -*-
// Simple example of how to use RadioHead to receive messages
// with a simple ASK transmitter in a very simple way.
// Implements a simplex (one-way) receiver with an Rx-B1 module

#include <RH_ASK.h>
#include <SPI.h> // Not actualy used but needed to compile

RH_ASK driver;

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);

struct dataStruct {
  float percent ;
  //unsigned long counter;

} myData;


void setup()
{
  lcd.begin(16, 2);
  //Serial.begin(9600);  // Debugging only
  if (!driver.init())
    lcd.setCursor(0, 0);
  lcd.print("No comms");
}

void loop()
{
  uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
  uint8_t buflen = sizeof(buf);

  if (driver.recv(buf, &buflen)) // Non-blocking
  {
    int i;

    // Message with a good checksum received, dump it.
    driver.printBuffer("Got:", buf, buflen);
    //memcpy(&myData, buf, sizeof(myData));
    //Serial.println("");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Tank Water Level: ");
    lcd.setCursor(5,1);
    lcd.print((char*)buf);
    //lcd.print(myData.percent);
    lcd.print("%");

    //    Serial.print("  press_hg: ");
    //    Serial.print(myData.press_hg);

    //    Serial.print("  temp: ");
    //    Serial.print(myData.temp);
  //  lcd.setCursor(0, 1);
  //  lcd.print("  counter: ");
  //  lcd.print(myData.counter);
  }
}

Updated Tx again with mapped data. Fixed output from Tx. Still get unwanted characters on Rx lcd 2nd line after percent figure. ie "73000011010. 73 is correct.

#include <RH_ASK.h>
#include <SPI.h> // Not actually used but needed to compile

RH_ASK driver;

#include <NewPing.h>
#define TRIGGER_PIN  10  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     9  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 400 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

int waterAtEmpty = 150; //distance in cm of sensor to water level at empty.
int waterAtFull = 40; //distance in cm from sensor to water level at full.

void setup()
{

  Serial.begin(9600);
  if (!driver.init());

}

void loop()
{
  int dist;

  delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
  dist = (uS / US_ROUNDTRIP_CM); //raw distance in cm.
  int waterRange = waterAtEmpty - waterAtFull; //difference between full and empty in cm.
  int adjDist = dist - waterAtFull; //water level from full in cm.
  // int percent = (adjDist * 100 + (waterRange / 2)/ waterRange); //water level from full expressed as %.
  int percent = map(adjDist, 110, 0, 0, 100);
  // const char *msg = percent;
  char msg[4];
  itoa(percent, msg, 10);
  //byte(percentage);
  //driver.send((uint8_t *)percent, 1);
  driver.send((uint8_t *)msg, strlen(msg));
  driver.waitPacketSent();
  delay(1000);

  Serial.print("dist ");
  Serial.print(dist);
  Serial.print("  adjDist ");
  Serial.print(adjDist);
  Serial.print("  Percent ");
  Serial.print(percent);
  Serial.println("");
}

I never worked with that specific library so stuff like this can happen. But what happens is that the buffer (buf) is not NULL terminated like a print expects. Think the easiest way is to manually insert it

// ask_receiver.pde
// -*- mode: C++ -*-
// Simple example of how to use RadioHead to receive messages
// with a simple ASK transmitter in a very simple way.
// Implements a simplex (one-way) receiver with an Rx-B1 module

#include <RH_ASK.h>
#include <SPI.h> // Not actualy used but needed to compile

RH_ASK driver;

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);

/*
struct dataStruct {
  float percent ;
  //unsigned long counter;

} myData;
*/


void setup()
{
  lcd.begin(16, 2);
  //Serial.begin(9600);  // Debugging only
  if (!driver.init())
    lcd.setCursor(0, 0);
  lcd.print("No comms");
}

void loop()
{
  uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
  uint8_t buflen = sizeof(buf);

  if (driver.recv(buf, &buflen)) // Non-blocking
  {
    int i;

    // Message with a good checksum received, dump it.
    driver.printBuffer("Got:", buf, buflen);
    
    buf[buflen] = '\0'; //insert NULL termination
    
    //memcpy(&myData, buf, sizeof(myData));
    //Serial.println("");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Tank Water Level: ");
    lcd.setCursor(5,1);
    lcd.print((char*)buf);
    //lcd.print(myData.percent);
    lcd.print("%");

    //    Serial.print("  press_hg: ");
    //    Serial.print(myData.press_hg);

    //    Serial.print("  temp: ");
    //    Serial.print(myData.temp);
  //  lcd.setCursor(0, 1);
  //  lcd.print("  counter: ");
  //  lcd.print(myData.counter);
  }
}

When you send the data, the NULL at the end of the string is NOT sent.

When you receive the data, the data is NOT a string (because there is no NULL at the end). You can not pass the data to a function that expects a string, and expect the function to behave correctly.

 if (driver.recv(buf, &buflen)) // Non-blocking
  {
      buf[buflen] = '\0';

Now, buf can be handled as a string.

UR friggin' awesome. Thanks for all your help. Just need to do some tidying up and it's done.

I learnt a few things along the way too!

(You too Paul) :slight_smile: