Buttonbox 2013 Software

From TSG Doc
Revision as of 15:58, 28 April 2014 by 131.174.110.254 (talk) (Created page with "<div>#include <EEPROM.h></div><div><br/></div><div>// start reading from the first byte (address 0) of the EEPROM</div><div>int address = 0;</div><div><br/></div><div>//...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
#include <EEPROM.h>

// start reading from the first byte (address 0) of the EEPROM
int address = 0;

// available modes
byte mode;
byte BITSI      = 0;
byte BITSI_extend = 1;
boolean NewCode       = false;


unsigned long TimeoutPulseLength = 10;  /* PulseLength in ms                 */
unsigned long TimeSend           = 0;   /* Debounce interval in ms           */
unsigned long TimeToSendOut      = 988;
unsigned long TimeoutPacingLED   = 500; /* Onboard Pacing LED interval in ms */

/* Reserved hardware wiring for enabling/disabling the HCT244 input buffer to I[8] */
int pinEnableBufIn = 13;

/* Reserved hardware wiring for forcing 27KOhm pull-up / pull-down to I[8] */
int pinPullUpDown  = 19;

/* There are 8 associated input bits D10=pin10, D11=pin11, D12=pin12
 * A0=pin14/AI0, A1=pin15/AI1 ,A2=pin16/AI2, A3=pin17/AI3, A4=pin18/AI3 */
//leonardo
//byte I[8] = { 10, 11, 19, 20, 21, 22, 23, 24 };
//uno
byte I[8] = { 10, 11, 12, 14, 15, 16, 17, 18};

/* declare SerialInChr to receive the desired Parallel_Out value in */
byte SerialInChr = 1;
byte SerialOutChr;

/* declare a time varable to remember the time when the Parallel_Out was set and to compare with TimeNow,
 * this way Parallel_Out can be implemented as a pulse with a desireded fixed pulseLength */
unsigned long TimeOnsetOut = 0;

/* declare bit state memory booleans to find out if input values have changed since the last looptest */
/*boolean State_I[8]      = { 
  LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};
boolean Prev_State_I[8] = { 
  LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};*/
boolean State_I[8]      = { 
  HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};
boolean Prev_State_I[8] = { 
  HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};



void setup()
{
  // configure input and output ports
  OutPortOutputMode();
  OutPortWrite(0);

  InPortInputMode();

  // configure onboard devices

  // enable input buffer
  pinMode(pinEnableBufIn, OUTPUT); 
  digitalWrite(pinEnableBufIn, LOW);

  // enable pullup resistors
  pinMode(pinPullUpDown, OUTPUT);
  digitalWrite(pinPullUpDown, HIGH);

  // blink stim leds
  /*SerialOutChr = B00000001;
  for (byte i = 0; i < 9; i++) {
   OutPortWrite(SerialOutChr);
   SerialOutChr = SerialOutChr << 1;
   delay(70);
   }*/
  // read a byte from the current address of the EEPROM
  //mode = EEPROM.read(address);
  mode = BITSI;

  // visual show mode to user
  /*for (byte i = 0; i < 6; i++) {
   OutPortWrite(mode);
   delay(250);
   OutPortWrite(0);
   delay(150);
   }
   */
  // what mode are we running?
  if (mode == BITSI) {
    Serial.begin(115200);
    while (!Serial) ;
    Serial.println("BITSI mode, Ready!");
  }
  else if (mode == BITSI_extend) {
    Serial.begin(115200);
    while (!Serial) ;
    Serial.println("BITSI_extend mode, Ready!");
  }

}


//--- Forever Loop method -----------------------------------------------------------------------------------------------------------


void loop()
{
  byte index = 0;

  //--- buttonbox_stream ---------------------------------------------------------------------------------------------
  /*if (mode == buttonbox_stream) {
    /* check if data has been sent from the computer 
    if (Serial.available()) {
      //--- read the most recent byte
      SerialInChr = Serial.read();
      OutPortWrite(SerialInChr);
      NewCode = true;
    } 

    //--- sync every ms-----------------
    while (micros () < TimeSend) {
    }

    Serial.print(readInPort());
    TimeSend = micros() + TimeToSendOut;
  } 

  //--- buttonbox_event ---------------------------------------------------------------------------------------------
  else if (mode == buttonbox_event){
    /* check if data has been sent from the computer 
    if (Serial.available()) {
      //--- read the most recent byte
      SerialInChr = Serial.read();
      OutPortWrite(SerialInChr);
      NewCode = true;
    } 

    //--- sync every ms-----------------
    while (micros () < TimeSend) {
    }

    /* send data if there is any change 
    if (SerialOutChr != readInPort()){
      SerialOutChr = readInPort();
      if (digitalRead(10) == 1){
        Serial.write(0b00000001);
      }
      else if (digitalRead(11) == 1){
        Serial.write(0b00000010);
      }
      else {
        Serial.write(0b00000100);
      }
    }
    TimeSend = micros() + TimeToSendOut;
  }*/

  //--- BITSI ------------------------------------------------------------------------------------------------------
  if (mode == BITSI){

    /* the debouncing or asking for the time takes to much processor time, events do not have the same time accuracy anymore
     tested this with ms timing of the buttonbox_stream, when it was implemented  ms timing was not reached*/
    byte index = 0;
    /* Process incoming serial characters
     *
     * The output bits are set immediately to reflect the value of the incoming serial character.
     */

    //--- sync every ms-----------------
    while (micros () < TimeSend) {
    }

    /* check if data has been sent from the computer */
    if (Serial.available()) {
      //--- read the most recent byte
      SerialInChr = Serial.read();
      //OutPortWrite(SerialInChr ^ 0b11111111);
      OutPortWrite(SerialInChr);
      NewCode = true;
    }

    /* Process input bits
     *
     * The input bits are monitored for state changes. If bit 0 goes from low to high, a capital 'A' character
     * is sent back to the PC over the serial line.
     * When it changes back from high to low, a lowercase 'a' character is sent to the PC.
     * For bits 0 to 7, the characters A-H and a-h are sent respectively.
     *
     * It is possible to connect mechanical switches to each of the input, because the input bits are debounced.
     * After a bit changes state, it will be ignored for a debouncing interval of [TimeoutDebounce] miliseconds.
     */

    /* loop over the bits, to check their states */
    for (index = 0; index < 8; index = index + 1) {
      State_I[index] = digitalRead(I[index]);
      /* check for bit state change = egde, but not within debouncing interval */
      if (Prev_State_I[index] != State_I[index]) {
        /* respond with the corresponding character */
        if (State_I[index] == HIGH) {
          Serial.print(char(97 + index));
        }
        else {
          Serial.print(char(65 + index));
        }

        /* save new previous bit state */
        Prev_State_I[index] = State_I[index];
      }
    }
    TimeSend = micros() + TimeToSendOut;

  }


  //--- change mode ---------------------------------------------------------------------------------------------
 //00x    = buttonbox_stream
  //000x   = buttonbox_event
  //0000x  = BITSI
  //00000x = personal implementation
   /*if ((SerialInChr == 0) && (NewCode)){
   NewCode = false;
   change_mode++;
   Serial.print(char(change_mode + 48));
   }
   else if ((change_mode > 1) && (SerialInChr != 0)) {
   if (change_mode == 2) {
   EEPROM.write(0, buttonbox_stream);
   Serial.print("new mode: stream, reboot!");
   setup();
   }
   else if (change_mode == 3) {
   EEPROM.write(0, buttonbox_event);
   Serial.print("new mode: event, reboot!");
   setup();
   }
   else if (change_mode == 4) {
   EEPROM.write(0, BITSI);
   Serial.print("new mode: BITSI, reboot!");
   setup();
   }
   else if (change_mode == 5) {
   EEPROM.write(0, pers_impl);
   Serial.print("new mode: personal, reboot!");
   setup();
   }
   change_mode = 0;
   }*/
}


// todo: implement writing to the input port
void InPortWrite(byte code)
{

}

void OutPortWrite(byte code)
{
  byte b, d;

  // perform bit calculations before updating the ports
  b = (code & B11000000) >> 6 | (PINB & B11111100);
  d = (code & B00111111) << 2;

  // update the ports
  PORTB = b;
  PORTD = d;
}

void OutPortOutputMode()
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
}

void InPortOutputMode()
{
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(14, OUTPUT);
  pinMode(15, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(17, OUTPUT);
  pinMode(18, OUTPUT);
}

void InPortInputMode()
{
  // configure all the pins of the input port as inputs
  pinMode(10, INPUT);    
  pinMode(11, INPUT);
  pinMode(12, INPUT);    
  pinMode(14, INPUT);    
  pinMode(15, INPUT);    
  pinMode(16, INPUT);    
  pinMode(17, INPUT);    
  pinMode(18, INPUT);

  // disable internal pullup
  digitalWrite(10, HIGH);  
  digitalWrite(11, HIGH);  
  digitalWrite(12, HIGH);  
  digitalWrite(14, HIGH);  
  digitalWrite(15, HIGH);  
  digitalWrite(16, HIGH);  
  digitalWrite(17, HIGH);  
  digitalWrite(18, HIGH);
}

void OutPortInputMode()
{
  // configure all the pins of the output port as inputs ;-)
  pinMode(2, INPUT);    
  pinMode(3, INPUT);
  pinMode(4, INPUT);    
  pinMode(5, INPUT);    
  pinMode(6, INPUT);    
  pinMode(7, INPUT);    
  pinMode(8, INPUT);    
  pinMode(9, INPUT);

  // enable internal pullup
  digitalWrite(2, HIGH);  
  digitalWrite(3, HIGH);  
  digitalWrite(4, HIGH);  
  digitalWrite(5, HIGH);  
  digitalWrite(6, HIGH);  
  digitalWrite(7, HIGH);  
  digitalWrite(8, HIGH);  
  digitalWrite(9, HIGH);
}


byte readInPort()
{
  byte b, c;

  b = PINB;
  c = PINC;

  return (((b & B00011100) >> 2) | ((c & B00011111)      << 3)) ^ (B11111111);
  /*          ^^^^^^^^  */

}

byte readOutPort()
{
  byte c, d;

  c = PINC;
  d = PIND;

  return ((d & B11111100) >> 2) |
    ((c & B00000011) << 6);
  /*          ^^^^^^^^  */

}