Convert bytes to decimal

Hello everyone !

I have am personal project of a car battery charger that needs some calibrations (voltage, current and some other particular parameters). Considering the fact that I intend to produce a great number of this chargers, I want to make a special device that will calibrate the charger automatically, simply and fast by connecting it to the output socket of the charger (without opening the charger case). And for this I need that that device (let's call it "Calibrator") to send some data to the charger, and charger to be able to recognize that data.

At the hardare level I want to do that communication by sending data packets composed from: A,B,C, where:

  • A - is a 10ms continuous HIGH state pulse;
  • B - is the address part (a bite that will tell to the charger in which subroutine should go);
  • C - is the data part (a bite that will tell to the charger some service data - for example: write the serial number).

Each bit from the data packet will be read by the same ADC port that reads the voltage at the car battery output. Because of the delay given by the RC filter placed before this ADC, in order to have all the bits correctly read, each bit will be transmitter for a period of 1ms.

Now, the problem is that I need a piece of code that could:

  • read the data packet;
  • extract the address and data parts;
  • converts the extracted data to decimal numbers so I could use them with the rest of the code.

In order to read the data packet I think I could declare 8 +8 variable (8 for address part and 8 for data part). But until now I don't have any idea about how could I convert the content of 8 Boolean numbers in a decimal number.

So this is now my problem: how could I convert 8 (or in fact, any other) number of boolean variables into a decimal number.

Do you have any idea that would help me with this conversion?

P.S. If you may have any other idea about how could I send small piese o data from my Calibrator to my charger, please share them with me :).

Regards,
Ciprian

how could I convert 8 (or in fact, any other) number of boolean variables into a decimal number.

Something like this maybe

boolean someData[] = {true, true, false, true, false, true, false, true};

void setup()
{
  Serial.begin(115200);
  byte aByte = 0;

  for (int b = 0; b < 8; b++)
  {
    bitWrite(aByte, 7 - b, someData[b] == false ? 0 : 1);
  }
  Serial.println(aByte, BIN);  
  Serial.println(aByte);
}

void loop()
{
}

Thanks, but I need to send the data from an digital output port (any digital output port, not just TX pin) to an digital input port (any digital output port, not just RX pin).

You asked

how could I convert 8 (or in fact, any other) number of boolean variables into a decimal number.

Is that not what you want after all ?

You're right.

Sorry, I forgot to mention that I need also to convert integers to boolean array (not only boolean array to integer). So now I have only half of the problem solved :).

I need also to convert integers to boolean array

So reverse the process in my example program. Use bitRead() to read the bits of the variable and use the value read to set the corresponding level of the boolean array.

I look forward to seeing your code.

Good morning,

I managed to get to a working code for my problem.

This is the code for the Transmitter.

int incomingValue;
int outputPin = A5;
void setup() {
Serial.begin(9600);
pinMode(outputPin, OUTPUT);

}

void loop() {
char buffer[] = {' ',' ',' ',' ',' ',' ',' '}; // Receive up to 7 bytes
while (!Serial.available()); // Wait for characters
Serial.readBytesUntil('n', buffer, 7);
incomingValue = atoi(buffer);
if(incomingValue != 0) {Serial.println(incomingValue); trimiteNumar(incomingValue);} 
}


void trimiteNumar(long Nr){
 int nrBit = 0;
 byte t = Nr;
 digitalWrite(outputPin, HIGH);
 delay(10);
 digitalWrite(outputPin, LOW);
 delay(10);
 while (nrBit < 8) {digitalWrite(outputPin, bitRead(t, nrBit));
                    Serial.println(bitRead(t, nrBit));
                    nrBit++;
                    delay(2);}
 digitalWrite(outputPin, LOW);                  
}

The part with:

char buffer[] = {' ',' ',' ',' ',' ',' ',' '}; // Receive up to 7 bytes
while (!Serial.available()); // Wait for characters
Serial.readBytesUntil('n', buffer, 7);
incomingValue = atoi(buffer);

is used as an fast and easy way to choose what number I want to be transmitted.

The Receiver code is:

int numarZecimal; 
int inputPin = A5;
int outputPin = 2;

void setup() {
pinMode(inputPin, INPUT);
pinMode(outputPin, OUTPUT);
Serial.begin(9600);
}
 
void loop() {
citireNumar();
Serial.println(numarZecimal);
}

void citireNumar(){
      int nrBit = 0;
      byte numarBinar = 0;
      boolean bitSincronizare = LOW; 
      boolean nivelLogicIntrare = LOW;
while(nivelLogicIntrare == LOW){nivelLogicIntrare = digitalRead(inputPin);}  
      long momentInitiereSincronizare = micros();
      long momentCurent = momentInitiereSincronizare;
      bitSincronizare = HIGH;
while ((momentCurent - momentInitiereSincronizare) < 9000) 
      { momentCurent = micros();
        nivelLogicIntrare = digitalRead(inputPin);
        if (nivelLogicIntrare == LOW) { bitSincronizare = LOW; break;}}
delayMicroseconds(11500);
while (nrBit < 8 && bitSincronizare == HIGH) {  nivelLogicIntrare = digitalRead(inputPin);
                                                bitWrite(numarBinar, nrBit, nivelLogicIntrare);
                                                Serial.println(nivelLogicIntrare);
                                                nrBit++;
                                                delay(2);
                                                 }
  numarZecimal = numarBinar;
  delay(10);
 }

Here, the “SerialPrint …” commands are used just to check what number is received.

In order to check if the communication is working, I installed the Transmitter code on an Arduino Uno board and the Receiver code on another Arduino Uno. Each Board was connected to a different PC (though their USB ports). The output pin of the Transmitter board (A5) was connected to the Receiver input pin (A5). Off course, the GNDs of both boards were connected together too. On each PC I opened a Serial Monitor window and I adjusted the Transmitter and Receiver codes until they worked.

I am satisfied with the result and the next step is to find a way to increase to 3 the number of bytes transmitted in one data packet: 1 byte for addressing (to choose where the data bytes should arrive) and 2 bytes for data.

Thanks UKHeliBob for tips ! :slight_smile:

char buffer[] = {' ',' ',' ',' ',' ',' ',' '}; // Receive up to 7 bytes
while (!Serial.available()); // Wait for characters
Serial.readBytesUntil('n', buffer, 7);

The array can only hold 6 bytes plus the terminating NULL.

Does whatever is sending data really send an 'n' after the data? Or does it send a '\n'?

I really don't know !

I took that piece of code from the internet because I needed a way to tell to the transmitter what number to transmit. I use it as it is, without trying to understand or modify it.

All that I can tell you about it, is that according to my tests, that piece of code is working fine for numbers smaller that 32768.

All that I can tell you about it, is that according to my tests, that piece of code is working fine for numbers smaller that 32768.

Well, that would be the upper limit for what can be stored in an int. So, if you want to handle values larger than that, you need a different type AND a different function. atol() maybe?

The biggest number I intend to write is the number of devices (car battery chargers) produced in one month. And, at least for now, there's little chance to produce more than 32768 devices per month :).