Convert a int to a binary array and vice versa

Hello :slight_smile:
I have a project with two arduino cards witch need to communicate a int (0 to 128) between them.
I tried different ways to make this working and it steel not working :frowning: (433mhz, 2.4ghz) and now I am trying to transfer an int by optical fiber. But, I would like to send and receive the data by digital (0,1) and not by analog.

So : - The arduino receives an int by serial port, then it converts this int to a binary array and send this binary array to the led → 1st arduino

  • The arduino receives the the light by a photoresistor (connected to analog port of the arduino) and when the value is over “x” > the bit is 1 else the bit is 0

I searched on the internet and I found this :

const byte numPins = 7;
byte pins[] = {13, 14, 15, 16, 17, 18, 19};
void setup() {
  Serial.begin(115200);
}

void loop() {
  while(!Serial.available()); // Do nothing until serial input is received
  byte num = Serial.read(); // Get num from somewhere
  for (byte i=0; i<numPins; i++) {
    byte state = bitRead(num, i);
    digitalWrite(pins[i], state);
    Serial.print(state);
  }
  Serial.println();
}

Original post here : https://forum.arduino.cc/index.php?topic=119261.0

I think it will work for me, I edited this a bit :

const byte numPins = 7;
const int ledPin = 6;


void setup() 
{
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() 
{
  // put your main code here, to run repeatedly:
 while(!Serial.available()); // Do nothing until serial input is received
 byte num = Serial.read(); // Get num from somewhere
 for (byte i=0; i<numPins; i++) 
 {
    byte state = bitRead(num, i);
    //digitalWrite(pins[i], state);
    delay(10);
    if(state == 1)
    {
      digitalWrite(ledPin,HIGH);
    }
    else
    {
      digitalWrite(ledPin,LOW);
    }
    //Serial.print(state);
  }
}

And I have a problem with the receiver, because I dont know how to convert the binarry array to a int.

Here is my RX code :

 int sensorPin = 3;      //Sensor witch will receive the data from the led
int limit = 1023/2;     //Var witch will define when the signal is "1" or "0"
int received;           //Var witch will stock the value from the analog pin
const byte numPins = 7; //How many bits ? (2^numPins)
int bits[7];

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
while(analogRead(sensorPin) < limit){} //while sensor pin < limit, do nothing
received = analogRead(sensorPin);                                            //Those whiles sync the data receiving
while(analogRead(sensorPin) > limit){} //while sensor pin < limit, do nothing
for(byte i=0; i<numPins; i++)
{
  received = analogRead(sensorPin);
  if(received < limit)
  {
    bits[i] = 0;
  }
  else
  {
    bits[i] = 1;
  }
}
}

Thanks for your help :slight_smile:

Your challenge is more how do you manage timing? If you have 2 consecutive bits set to 0 (or to one), you will not see any blinking, so how many 0 (or 1) do you count? At the moment you rush through reading the sensor and assume a new bit is there...

You need to read about sending serial information theory

Once you have that working you can build your byte B each time you have captured a new bit by doing

B = 2*B + bitvalue;

Thanks or your reply J-M-L, the data will by synced like this :

(where 1 is the led high and 0 the led low)

000000000 > No data

01<Means that the data will comes up :slight_smile:

so an int will come like this :

“01”(intro signal)“0110101”(data)

Say your byte is 01110000 or 01000000 or 011111110

What does your light signal looks like?

Off On to signal new data and then Off On and Off for a certain time in the 3 cases case. So the sensor on the reader sees

Off On Off On Off

How do you deal with timing to distinguish two consecutive bits is a critical question (hence baud rates for example)

I want to put a delay of 10 ms between the sinals, i’m not woking with the bauds (to hard for me) :slight_smile:

So when I get the data, the code will look like :

for(byte i=0; i<numPins; i++)
{
received = analogRead(sensorPin);
while(received < limit)
{
received = analogRead(sensorPin);
bits = 0;

  • delay(11);*
  • i++;*
  • }*
  • while(received > limit)*
  • {*
  • received = analogRead(sensorPin);*
    _ bits = 1;_
    * delay(11);*
    * i++;*
    * }*
    }
    I changed the if(s) to whiles and maybe this will not work, I have a couple of tests to do :slight_smile:

so assume infinite speed of light so when you emit it's always received instantly.

10ms is a LOOOOOONG time by the way, it means you can send on 100 bits per second, roughly 12 characters per seconds - but that's OK if speed is not the pb.

start pattern
0 for 10ms
1 for 10ms

sending pattern

bit0 for 10ms
bit1 for 10ms
bit3 for 10ms
bit4 for 10ms
bit5 for 10ms
bit6 for 10ms
bit7 for 10ms

--> if you need to send multiple bytes you need a start pattern that can't happen through normal byte sending. So I would probably recommend something flickering faster for example

start pattern
0 for 1ms
1 for 1ms
0 for 1ms
1 for 1ms
0 for 5ms

if you detect that "dance" on your sensor, then you know something will happen for the next 80ms

sending pattern

bit0 for 10ms
bit1 for 10ms
bit2 for 10ms
bit3 for 10ms
bit4 for 10ms
bit5 for 10ms
bit6 for 10ms
bit7 for 10ms

best is to sample after giving a bit of time to let the signal become stable

you could also envision to send a control bit to (checksum) to help verify that the signal was well received

Thanks for your time and replies :wink:

I choose the time of 10ms because I was worried about the photoresistor, I think it cannot receive data every ms (I saw that with a multimeter) and that is why I chose 10ms.
I just need to transfer an int in a long range (+100m) ~every second so 10ms is enough :slight_smile: , I also would like to improve the fiability of the data that travel in the optical fiber (no errors :p), a checksum will double the price (2*100m optical fiber = 60€ ; and the code will get a bit hard for me), but it still a good idea :slight_smile:

If the photoresistor seems to work at 1ms why not ? ^^

I will do some tests with the arduinos in 1 or 2 hours :slight_smile:

100m you can easily cover with a NRF24L01 (depending on your environment) and you save 58€ out of your 60€ :slight_smile:

checksum does not need a second fiber optic, just sending one extra bit.

Thank you again for your replies, the range of the NRF24L01 is a bit low (I have bought some and they doesn't work, because of their price :stuck_out_tongue: )

I have found something very interesting : A long range 433mhz modem, that you can find on ebay :
http://www.ebay.fr/itm/Semtech-LoRa-SX1276-SX1278-UART-Interface-RF-wireless-module-DRF1278DM-/191273642230
or on tindie :

My problem is that the photoresistor is not adapted for optical fiber data transmission, so if someone read this post, don't use a photoresistor for those applications, and look for a long range radio modem (at less you should buy it for 20$ minimum)

(please dont buy this https://www.amazon.com/SUNKEE-receiver-Superregeneration-Wireless-Transmitter/dp/B008A4UWK6/ref=sr_1_3?ie=UTF8&qid=1481359869&sr=8-3&keywords=433mhz you will need an external antenna and that's very boring to make... the range without antenna is about 10m at 5V or 3.3V ...)

Conclusion : Sensor was not adapted, data transmition was sh**. Search for log range radio modem :wink:

I hope this topic will help some of you ^^

Ok - i bought NRF24L01 with external antenna provided and Transmitter power amplifiers and Receiver preamplifiers for 5 bucks from the Far East... i get easily many hundred meters coverage at reasonable baud rate

Most of the problem I've seen users having is that the 3.3V Power to the module does not have enough current capability, or current surges cause problem (intermittent operation are because of insufficient current or electrical noise on the 3.3V Power supply) and this can be easily addressed.

See this for ideas