Hey, i have a problem about converting byte to char. I tried to send 8 character and decode it using interrupt. The byte i decode works just fine, but when i convert it, it always receive the char only after i resend it
For example, i send <0 2 e>! but there's nothing on the Serial monitor. After i try to resend <0 2 e>! there is a <0 2 e>! But when i send another data, like <1 2 a>! the printed data is the <0 2 e>! that i've sent before.
This is the code:
byte lock=0;
int ya=1;
void baca(int sementara){
if (ya<9){
if ((sementara < 4700)&&(sementara > 4400)){
ya=1;
tambah=1;
lock=0;
//"header";
} else if ((sementara < 1800)&&(sementara > 1500)){
lock=tambah+lock;
tambah=tambah*2;
ya++;
//"byte 1"
 } else if ((sementara < 700)&&(sementara > 400)){
  tambah=tambah*2;
  ya++;
  //"byte 0"
  }else{
   //Serial.print("x");
   }
  Â
}else if (ya==9){
if (l<8){
isipesan[l]=char(lock);
//Serial.print(isipesan[l]);
l++;
if(l==8){
String terima;
for(int p=0;p<8;p++){
terima=terima+isipesan[p];
}
Serial.print(terima);
l=0;
}
ya=1;
tambah=1;
lock=0;
}else{
 Serial.println("Error bit");
 }
}
}
I tried to decode IR Signal by reading the pulse length and convert the bit to char then to string before send it to the serial, and i'm try to convert the bit to the char from LSB to MSB
If i receive signal between 1500 and 1800 it means 1 and if between 400 and 700 it means 0.
The Tx code works fine since i checked using the oscilloscope.
Here's my full code on the Rx:
volatile int durasi;
volatile int prev_time;
volatile int data_simpan[255];
int l=0;
unsigned int lol;
int x=0;
byte tambah;
char isipesan[50];
void setup() {
Serial.begin(250000);
attachInterrupt(digitalPinToInterrupt(3), jatuh, RISING);
}
void loop() {
}
void jatuh() {
detachInterrupt(digitalPinToInterrupt(3));
prev_time=micros();
attachInterrupt(digitalPinToInterrupt(3),naik,FALLING);
}
void naik(){
detachInterrupt(digitalPinToInterrupt(3));
durasi=micros()-prev_time;
data_simpan[x]=durasi;
baca(data_simpan[x]);
x++;
attachInterrupt(digitalPinToInterrupt(3), jatuh, RISING);
}
byte lock=0;
int ya=1;
void baca(int sementara){
if (ya<9){
if ((sementara < 4700)&&(sementara > 4400)){
ya=1;
tambah=1;
lock=0;
//"header";
} else if ((sementara < 1800)&&(sementara > 1500)){
lock=tambah+lock;
tambah=tambah*2;
ya++;
//"Logic 1"
 } else if ((sementara < 700)&&(sementara > 400)){
  tambah=tambah*2;
  ya++;
  //"Logic 0"
  }else{
   Serial.print("x");
   }
  Â
}else if (ya==9){
if (l<8){
isipesan[l]=char(lock);
l++;
if(l==8){
String terima;
for(int p=0;p<8;p++){
terima=terima+isipesan[p];
}
Serial.print(terima);
 l=0;
}
ya=1;
tambah=1;
lock=0;
}else{
 Serial.println("Error bit");
 }
}
}
septillion:
And why attach and detach the interrupt? Why not set it to CHANGE and just read the pin? Only if the signal is VERY fast that changes it.
micros() returns an unsigned long, so using a singed int is asking for trouble
Thanks, i thought i detach the interrupt will protect the duration in this micros();?
durasi = micros() - prev_time;
septillion:
255 int's, hole crap, why do you need so much memory?
And worst, nothing is limiting x to a max of 254 so it will overflow data_simpan
And you should keep the interrupt SHORT and don't call Serial. So don't call Chewbacca baca in it. Set a flag you want to do that and do it in loop().
But what should the char contain? Just the value from the byte?
So it's better if i changed it to unsigned long?
I'm sorry but i don't get it what do you mean by set a flag, how can i put it in loop()? Can you give an example?
And yes just the value, like if the binary is 00001100 i'll save the '0' char to isipesan[p] and wait until 8 characters before convert it to string and send it to serial.
when you reach the end of the array (and if you use a byte (unsigned on 8 bits) then adding 1 to 255 automatically goes back to zero so you won't overflow your array
Thank you. But after i change it, it still print only the data that i sent before
Am i wrong at converting byte to char array? I tried this code too. But it still doesn't work.
//6 6 2017
//Data yang dikirim jadi batas id, diteruskan lewat serial
volatile unsigned long durasi;
volatile unsigned long prev_time;
volatile int data_simpan[25];
int l = 0;
int x, charke = 0;
//byte tambah;
byte bitArray[8];
byte byteArray[16];
byte chrmsk;
//int bitke;
int jum;
String terima;
void setup() {
 Serial.begin(250000);
 attachInterrupt(digitalPinToInterrupt(3), jatuh, RISING);
}
void loop() {
}
void jatuh() {
 detachInterrupt(digitalPinToInterrupt(3));
 prev_time = micros();
 attachInterrupt(digitalPinToInterrupt(3), naik, FALLING);
}
void naik() {
 detachInterrupt(digitalPinToInterrupt(3));
 durasi = micros() - prev_time;
 data_simpan[x] = durasi;
 baca(data_simpan[x]);
 if ( x < 25 ) {
  x++;
 } else {
  x = 0;
 }
 attachInterrupt(digitalPinToInterrupt(3), jatuh, RISING);
}
void baca(int sementara) {
 if ((sementara < 4700) && (sementara > 4400)) {
  jum = 0;
 } else if ((sementara < 1800) && (sementara > 1500)) {
  bitArray[jum] = 1;
  jum++;
  if (jum == 8) {
   terjemah();
   jum = 0;
  }
 } else if ((sementara < 700) && (sementara > 400)) {
  bitArray[jum] = 0;
  jum++;
  if (jum == 8) {
   terjemah();
   jum = 0;
  }
 } else {
  //Serial.print("x");
 }
}
void terjemah() {
 binertochar();
 if (charke < 8) {
  byteArray[charke] = chrmsk;
  charke++;
  if (charke == 7) {
   terima = String((char*)byteArray);
   Serial.println(terima);
  }
  if (charke == 8) {
   byteArray[7]=0;
   charke = 0;
  }
 }
 jum = 0;
 return;
}
void binertochar() {
 int tambah = 1;
 chrmsk = 0;
 for (int i = 8; i > 0; i--) {
  if (bitArray[i - 1] == 1) {
   chrmsk = chrmsk + tambah;
  }
  tambah = tambah * 2;
 }
}
I tried this code because it put the convert outside the byte reading. But, this one just print the whole wrong character
Just do it on the fly! If you see the end of a bit (aka, after a falling) just check the time. A simple if is quick. And based on that add a 0 or a 1 to a variable.
I can't really help you with that because I have no clue what ya, tambah and lock do... That just sounds ipsum lorum to me...
septillion:
I can't really help you with that because I have no clue what ya, tambah and lock do... That just sounds ipsum lorum to me...
Ya is a counter, so i'll know when i get 8 bit. Lock is a zero for odd accumulator (bit 1) and tambah is for multiplying/even accumulator.
For example if i receive 00001100 the 0 will be multiplied by two, stored in tambah for 4 times so tambah will be 8, and the one will be multiplied by two and added by one. Then it found 1 so it will be 17, and then it found another 1 so it will be 35 and so on..