Converting a Binary string to a decimal

hello

i have a string with 11 bits in it in binary and would like to make this into a decimal how can i do it the stuff in the string looks like this 10111100111 and when this is converted to a decimal should be 3023. the number in the binary will be changing and i need to make it into the decimal number to be able to do calculations with it

int readBinaryString(char *s) {
  int result = 0;
  while(*s) {
    result <<= 1;
    if(*s++ == '1') result |= 1;
  }
  return result;
}

void init() {
  int value = readBinaryString("10111100111");
}

You're welcome.

1 Like

sorry im new to this programming a have the binary in a string and a can print it to serial monitor using Serial.println(data);
when i do this i get the binary out. the data part is a string how can i change this into a int

First, you need to brush up on your binary. The number 10111100111 represents:
1024 + 256 + 128 + 64 + 32 + 4 + 2 + 1 = 1511 != 3032

One way to convert a character string representing a binary number is to use the function strtol with specifiying base 2 for the character string. http://www.cplusplus.com/reference/cstdlib/strtol/

void setup() {
 Serial.begin(9600);
 char input_binary_string[] = "10111100111";
 long value= strtol(input_binary_string, NULL, 2);
 Serial.println(value);
}
void loop() {
}

hi again how could i add bits to the string im using a libaray that outputs data as individule chars like this

if( vw_get_message(buf, &buflen) )
 
    {
            lcd.setCursor(0, 0);
            lcd.print("Outdoor:");    
           
      for (i = 0; i < buflen; i++)
       
        { 
            lcd.write(buf[i]);
          
                       
        }
       
            lcd.setCursor(14, 0);
            lcd.print((char)223);
           
            Serial.print(value);
            
            lcd.print("C");
     }

that is to get it onto a lcd display but the problem is that i cannot use that number as a int when it is a char how can i use that code you posted to also get a number in an int format aswell as being able to print it to the lcd display

First, you will have to post your complete code, sending and receiving, and provide a bit of background information about your sensors, and information you are trying to send with your code,. and what you would like to do with it at the receiving side.

hi my code is at the moment going to just send a temperature reading to another arduino with the lcd that will display the temperature and also the temperature of its own location. i want the value sent that is going to the lcd to be an int so i can use it to turn things like and led on when it goes below a certain temperature and other things like this

this is the transmitter code

#include <VirtualWire.h>

char msg[6];
const int sensorPin = A4;

void setup() {
  
vw_setup(2000);
vw_set_tx_pin(12);

}

void loop() {

int sensorVal = analogRead(sensorPin);
float voltage = (sensorVal / 1024.0) * 5.0;
float temperature = (voltage - .5) * 100;
dtostrf(temperature, 6, 2, msg);
vw_send((uint8_t *)msg, strlen(msg));
vw_wait_tx();
delay(200);

}

and the reciver

#include <LiquidCrystal.h>
#include <VirtualWire.h>
char data = "";
  float temp;
  int tempPin = 0;
 
  int i;

  LiquidCrystal lcd(8, 7, 5, 4, 3, 2);



void setup(){
 
  Serial.begin(9600);
  lcd.begin(16, 2);
 
  vw_setup(2000);
  vw_rx_start();
  vw_set_rx_pin(11);
}

void loop(){
 
  lcd.setCursor(0, 1);
  lcd.print("Indoor: ");
  lcd.print(temp);
  Serial.println(temp);
  lcd.setCursor(14, 1);
  lcd.print((char)223);
  lcd.print("C");
 
  temp = analogRead(tempPin);
  temp = temp * 0.55168125;
 
 
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;

  if( vw_get_message(buf, &buflen) )
 
    {
            lcd.setCursor(0, 0);
            lcd.print("Outdoor:");    
           
      for (i = 0; i < buflen; i++)
       
        { 
            lcd.write(buf[i]);
            //char input_binary_string[] = "";
            data = data + buf[i];

            
        }
       
            lcd.setCursor(14, 0);
            lcd.print((char)223);
            long value= strtol(data, NULL, 2);
            Serial.print(value);
                       // Serial.print((char)223);
            lcd.print("C");
     }
    
          }

I think there is a more simple way to go than using dtostrf to convert the temperature data to a string for transmission, and then converting it back into a float on the receive with atof. VirtualWire sends bytes, and you can cast the float into bytes (there are 4 in a float) for transmission with (uint8_t*)&myFloat and put them back together in the receiving sketch with memcpy of the received buffer into a float. Serial.print(), and lcd.print() can both handle floats to however many decimal places you desire with syntax like Serial.print(myFloat,2) for 2 dps. There is no need to present them with chars in order to print numbers. The casting to bytes, sending them, and reconstructing them with memcpy is useful for more complex data structures like arrays and structs.

Here's your Tx sketch modifed to eliminate the string conversion

#include <VirtualWire.h>

//char msg[6];
const int sensorPin = A4;

void setup() {
  vw_setup(2000);
  vw_set_tx_pin(12);
}

void loop() {

  int sensorVal = 155;//analogRead(sensorPin);
  float voltage = (sensorVal / 1024.0) * 5.0;
  float temperature = (voltage - .5) * 100;
  //dtostrf(temperature, 6, 2, msg);
  //vw_send((uint8_t *)msg, strlen(msg));
  vw_send((uint8_t *)&temperature, sizeof(temperature));
  vw_wait_tx();
  delay(1000);
}

And here's a Rx sketch demonstrating the use of memcpy to recreate a float

#include <VirtualWire.h>
void setup()
{
  Serial.begin(9600);
  Serial.println("setup");
  vw_setup(2000);
  vw_set_rx_pin(11);
  vw_rx_start();
}

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

  if (vw_get_message(buf, &buflen))
  {
    Serial.print("Got 4 bytes of the float: ");

    for (int i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
      Serial.print(" ");
    }
    Serial.println();
    
    float temperature;
    memcpy(&temperature, buf, buflen);
    Serial.print ("Temperature = ");
    Serial.println(temperature,2);
    if (temperature >= 25.55) {
      Serial.println("You can treat me like a number.");
    }
  }
}

cattledog:
I think there is a more simple way to go than using dtostrf to convert the temperature data to a string for transmission, and then converting it back into a float on the receive with atof. VirtualWire sends bytes, and you can cast the float into bytes (there are 4 in a float) for transmission with (uint8_t*)&myFloat and put them back together in the receiving sketch with memcpy of the received buffer into a float. Serial.print(), and lcd.print() can both handle floats to however many decimal places you desire with syntax like Serial.print(myFloat,2) for 2 dps. There is no need to present them with chars in order to print numbers. The casting to bytes, sending them, and reconstructing them with memcpy is useful for more complex data structures like arrays and structs.

I was having similar issues trying to transmit my temp sensor data via MQTT. And then, display that data via Home Assitant. On Home Assistant, the values are blank

I had help with getting to this point. It does EXACTLY what I want. It does display the temp data on serialPrint and MQTT. BUT, not Home Assistant. : (

  //  ****************  TEMPERATURE (F) ************************
#define INT_STR_SIZE 16
  char buffer[INT_STR_SIZE];
  dtostrf(9.0 * bme.readTemperature() / 5.0 + 32.0, 3, 0, buffer);
  Serial.print("Temperature = ");
  Serial.print(buffer);
  Serial.println(" *F");
  client.publish("BME280/TempF", buffer);


  //  ****************  TEMPERATURE (C) ************************
  dtostrf(bme.readTemperature(), 3, 0, buffer);
  Serial.print("Temperature = ");
  Serial.print(buffer);
  Serial.println(" *C");
  client.publish("BME280/TempC", buffer);


  //  ****************  HUMIDITY  *********************
  dtostrf(bme.readHumidity(), 3, 0, buffer);
  Serial.print("Humidity = ");
  Serial.print(buffer);
  Serial.println(" %");
  client.publish("BME280/Humidity", buffer);


  //  ****************  PRESSURE  *********************
  dtostrf(bme.readPressure() / 3386.39, 3, 2, buffer);
  Serial.print("Pressure = ");
  Serial.print(buffer);
  Serial.println(" in");
  client.publish("BME280/Pressure", buffer);


  //  ****************  ALTITUDE  *********************
  //    Serial.print("Approx. Altitude = ");
  //    Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA)+4);//   +4 to correct altitude
  //    Serial.println(" m");


  Serial.println();

So I started searching and found your post. Is the use of dtostrf "outdated"? Meaning: there is a better way? Maybe I need to tweak HA configuration file? Any Home Assistant users out there?

  dtostrf(9.0 * bme.readTemperature() / 5.0 + 32.0, 3, 0, buffer);

I REALLY do not understand using dtostrf() to convert a float to a string with no decimal points.

Just store the value in an int, and use itoa() if you NEED a string.

PaulS:
Just store the value in an int, and use itoa() if you NEED a string.

Maybe you can help me with this thread: [SOLVED] Adafruit BME280 Temp, Humidity, Barometric pressure sensor - #22 by marine_hm - Sensors - Arduino Forum
Starting with #7?