davidbuckley.net
home 8 July 2023

Arduino - IRin, serout and serin routines.

IRin - to receive Sony IR commands, just like a PicAxe microcontroller.
serout - at 9600 baud, simple Serial out like in Parallax and PicAxe Basics.
serin - at 9600 baud, simple Serial in like in Parallax and PicAxe Basics.

I wrote the serial routines because I didn't have enough serial ports and needed to send a byte and get a return byte for my TecArm5 controller.
I wrote the IRin routine because I found the Arduino IR-library to be totaly unreliable for robot control, half the time it would give wrong codes or no codes at all. My routine will receive all basic codes to 127.

History
8 July 2023 corrected html because using the lessthan sign corrupted the displayed text.

//===========================================================
// PicAxe Remote Control TVR010 
// other buttons don't send codes and/or change controller mode
//                        [power]21
//               [^]16
//          [<]19     [>]18  
//               [v]17
// [bar]96 [tent]54 [vcross]37 [xcross]20      
//       [1]0     [2]1       [3]2
//       [4]3     [5]4       [6]5
//       [7]6     [8]7       [9]8
//       [-]98    [0]9       [+]11
// [square]54  [triangle]50  [circle]55 
//    [L]22       [X]56        [F]57

//------------------------------
To avoid waiting for the IR time-out if no IR commands are being sent, test the inIRpin
QIR:
  if(inIRpin==0) {   //pulses low if IR being received, saves waiting for IRmsg
    IRcmnd =IRin(inIRpin);
   // good idea to make a beep here so user knows IRcode received and can take finger off the button 
   }
//------------------------------
byte IRin(byte pin) 
{
//header =2400us;  //2418
//1 =1200us
//0 =600us
//each bit preceded by 600us off
  byte inbyte =0;
  byte inbit;
  int pulsetime;
  
WaitHeader:
  while( digitalRead(pin)==1 ) {}
Header: 
  pulsetime =pulseIn(pin,LOW);
  if (pulsetime<2200) { goto WaitHeader; }
Message:
  for(inbit=0; inbit<7; inbit++) {         // Sony codes are 0-127 so only 7 bits, LSB first
    pulsetime =pulseIn(pin,LOW);
    if (pulsetime<1000) { bitWrite(inbyte, inbit, 0); } else { bitWrite(inbyte, inbit, 1); }
  } 
  return inbyte;
}
//===========================================================
void serout96(boolean logic, byte pin,byte Ccmnd)   //9600n1  logic 1=true, 0=inverted(5v RS232)
{
  byte btc =101;     //96 - 106      bit-time-control
  byte btt =99;      //bit-time-transmit, a bit less for FOR loop  
  byte i;            //counter
  pinMode(pin, OUTPUT);   
startbit:
  digitalWrite(pin,!logic);
  delayMicroseconds(btc);
Character:
  for(i=0; i<8; i++) {
    digitalWrite(pin,!logic^bitRead(Ccmnd,i));
    delayMicroseconds(btt);  
   }
stopbit:
  digitalWrite(pin,logic);
  delayMicroseconds(btc);
}
//-----------------------------------------------------------
byte serin96(boolean logic, byte pin)   //9600n1  logic 1=true, 0=inverted(5v RS232)
{
  byte btc =105;     //96 - 106      bit-time-control   // was 101 but bit0 was flaky
  byte btr =105;     //100 - 112     bit-time-receive
  byte i;            //counter
  byte inbyte =0;
  byte inbit;
  unsigned long time;
  const byte serin96timeout =50;
  pinMode(pin, INPUT);
 
  time =serin96timeout +millis(); 
  while(digitalRead(pin)==logic)  { if(time<millis()) {return 0;} }
startbit:
  delayMicroseconds(btc);  
Character:
  for(i=0; i<8; i++) {
    bitWrite(inbyte, i, !logic^digitalRead(pin));
    delayMicroseconds(btr);
   }
stopbit:
  delayMicroseconds(btc); 
  return inbyte;
}
//===========================================================