Buttonbox 2013 Software

From TSG Doc
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
/*
leonardo heeft andere pin mapping
 digitalWrite(pin, LOW); digitalWrite(pin, HIGH); -> 56 cycles
 CLR(PORTB, 0) ; SET(PORTB, 0); -> 2 cycles
 The macros used:
 #define CLR(x,y) (x&=(~(1<<y)))
 #define SET(x,y) (x|=(1<<y))
 switch dender is 1ms
 total BITSI loop takes 88 us 
 */

#include <EEPROM.h>
#include <SPI.h>
#include <digitalWriteFast.h>

#define DATAOUT 11//MOSI 
#define DATAIN  12//MISO 
#define SPICLOCK  13//Clock 

int address = 0;

// available modes
byte mode             = 1;
byte ShiftAnalogOut   = 2;
byte ShiftLED         = 3;
byte ShiftOutput      = 4;
byte ShiftAnalogIn    = 5;
//leonardo
//byte I[8] = { 6, 7, 8, 9, 20, 21, 22, 23};
//uno
//byte I[8] = { 6, 7, 8, 9, 16, 17, 18, 19};
//duemilanove
byte I[8] = { 6, 7, 8, 9, 16, 17, 18, 19};
unsigned long TimeOnSet_I[8]  = {
  0, 0, 0, 0, 0, 0, 0, 0};
boolean       Debouncing_I[8] = {
  false, false, false, false, false, false, false, false};

byte SerialInChr      = 1;
byte SerialOutChr     = 0;
byte AnalogInChr1     = 1;
byte AnalogInChr2     = 2;
byte AnalogOutChr1    = 0;
byte AnalogOutChr2    = 0;
byte TimeStamp        = 0;
byte SpeakerPin       = 14;
byte VoicekeyPin      = 15;
byte index            = 0;
byte BITSI            = 1;
byte BITSI_extend     = 2;
byte Personal         = 3;
char Detect_Function  = 'N';
byte treshold_Sound   = 1;     
byte treshold_Voice   = 25;     


unsigned long TimeoutDebounce = 2;
unsigned long TimeNow         = 0;
unsigned long TimeNow2        = 0;

unsigned int sensorValue_low_Voice = 1500;         // the sensor value
unsigned int sensorValue_high_Voice = 0;         // the sensor value
unsigned int sensorValue_high_Sound = 0;         // the sensor value
unsigned int ReadValue;

boolean Detect_Voice = false;
boolean Detect_Sound = false;
boolean Start_Tone = false;
boolean Send_An = false;
boolean Send_Marker = false;
boolean Recieve_led = false;
boolean Send_Led = false;


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

void setup()
{
  Serial.begin(115200);
  SPI.begin();
  SPI.setBitOrder(MSBFIRST); 
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  pinMode(SpeakerPin, OUTPUT);
  pinMode(VoicekeyPin, INPUT);
  pinMode(ShiftOutput, OUTPUT);
  pinMode(ShiftLED, OUTPUT);
  pinMode(ShiftAnalogIn, OUTPUT);
  InPortInputMode();
  SendOutput(255);

  //mode = EEPROM.read(address);
  ReadAndSendInput();
  if ((State_I[0] == LOW)  && (State_I[1] == HIGH) && (State_I[2] == HIGH) && (State_I[3] == HIGH) && 
      (State_I[4] == HIGH) && (State_I[5] == HIGH) && (State_I[6] == HIGH) && (State_I[7] == LOW)){
    mode = BITSI;
    EEPROM.write(address, mode);
      }
  else if ((State_I[0] == HIGH) && (State_I[1] == LOW) && (State_I[2] == HIGH) && (State_I[3] == HIGH) && 
           (State_I[4] == HIGH) && (State_I[5] == HIGH) && (State_I[6] == HIGH) && (State_I[7] == LOW)){
     mode = BITSI_extend;
     EEPROM.write(address, mode);
      }
  else{
   mode = EEPROM.read(address);
  }
  mode = BITSI;

  //########VOICE##########################################
  // callibrate the voice:
  /*if (mode == BITSI_extend) {
    Callibrate_Voice();    
    Serial.print("sensorValue_low_Voice = ");
    Serial.println( sensorValue_low_Voice );
    Serial.print("sensorValue_high_Voice = ");
    Serial.println( sensorValue_high_Voice );
  }*/
  //########SOUND##########################################
  // callibrate the Sound:
  if (mode == BITSI_extend) {
    Callibrate_Sound();
    //Serial.print("sensorValue_high_Sound = ");
    //Serial.println( sensorValue_high_Sound );
  }
  ///#######################################################

  // visual show mode to user
  for (byte i = 0; i < 1; i++) {
    SendLED(255);
    delay(500);
    SendLED(0);
    //delay(500);
  }

  if (mode == BITSI_extend) {
    tone(SpeakerPin, 956,100);//laag
    delay(200);
    tone(SpeakerPin, 1915,100);//hoog
    delay(100);
    noTone(SpeakerPin);
  }
  
  // what mode are we running?
  if (mode == BITSI) {
    Serial.begin(115200);
    Serial.println("BITSI mode, Ready!");
  }
  else if (mode == BITSI_extend) {
    Serial.begin(115200);
    Serial.println("BITSI_extend mode, Ready!");
  }
  else if (mode == Personal) {
    Serial.begin(115200);
    Serial.println("Personal mode, Ready!");
  }

}

//--- Forever Loop method -----------------------------------------------------------------------------------------------------------
void loop()
{

  //--- BITSI ------------------------------------------------------------------------------------------------------
  if (mode == BITSI){
    //TimeNow2 = micros();
    byte index = 0;

    if (Serial.available()) {
      SerialInChr = Serial.read();
      SendLED(SerialInChr);
      SendOutput(SerialInChr);
    }

    TimeNow = millis();

    ReadAndSendInput();
    //ReadValue = ReadAnalogChannel(1); 
    //Serial.println(ReadValue,DEC); 

    //TimeNow2 = micros() - TimeNow2;
    //Serial.println(TimeNow2);
  }

  //--- personal implementation ---------------------------------------------------------------------------------------------
  else if (mode == BITSI_extend) {
    
    //TEST ANALOG OUT
    //TEST BUTTONS &
    //TEST MARKER 
    //TEST SOUND KEY &
    //TEST ANALOG IN &
    //TEST LEDS
    //TEST TONE &
    
    
    //TimeNow2 = micros();
    byte index = 0;

    if (Serial.available()) {
      SerialInChr = Serial.read();
      if (char(SerialInChr) == 'R'){  
        Detect_Function = 'N';}
      else if (Detect_Function == 'N'){
        if ((char(SerialInChr) == 'M') ||  
           (char(SerialInChr) == 'Y') ||
           (char(SerialInChr) == 'Z') ||
           (char(SerialInChr) == 'C') ||
           (char(SerialInChr) == 'A') ||
           (char(SerialInChr) == 'D') ||
           (char(SerialInChr) == 'L')) {
           Detect_Function = char(SerialInChr);
        }
        else if (char(SerialInChr) == 'T') {Start_Tone = true;}
      }
      else if(Detect_Function == 'D'){
        Detect_Function = 'N';
        if (char(SerialInChr) == 'S') {Detect_Sound = true;}
        if (char(SerialInChr) == 'V') {Detect_Voice = true;}}
      else if(Detect_Function == 'M'){
        Detect_Function = 'N';
        Send_Marker = true;}
      else if(Detect_Function == 'Y'){
        Detect_Function = 'N';
        Send_An = true;
        AnalogOutChr1 = SerialInChr;}
      else if(Detect_Function == 'Z'){
        Detect_Function = 'N';
        Send_An = true;
        AnalogOutChr2 = SerialInChr;}
      else if(Detect_Function == 'C'){
        Detect_Function = 'N';
        if (SerialInChr == 'S') {Callibrate_Sound();
        //Serial.print("sensorValue_high_Sound = ");
        //Serial.println( sensorValue_high_Sound );
        }
        else if (SerialInChr == 'V') {Callibrate_Voice();}}
      else if(Detect_Function == 'A'){
        Detect_Function = 'N';
        if (char(SerialInChr) == '1') {Serial.print(ReadAnalogChannel(1));}
        else if (char(SerialInChr) == '2') {Serial.print(ReadAnalogChannel(2));}
        else if (char(SerialInChr) == '3') {Serial.print(ReadAnalogChannel(3));}
        else if (char(SerialInChr) == '4') {Serial.print(ReadAnalogChannel(4));}}
      else if(Detect_Function == 'L'){
        Detect_Function = 'N';
        if (char(SerialInChr) == 'X'){
          SendLED(0);
          Send_Led = false;
          Recieve_led = false;}
        else if (char(SerialInChr) == 'I'){
          Send_Led = false;
          Recieve_led = true;}
        else if (char(SerialInChr) == 'O'){
          Send_Led = true;
          Recieve_led = false;}
      }
      else{Detect_Function = 'N';}
    }

    TimeNow = millis();

    if (Send_Marker){
      SendOutput(SerialInChr);
      Send_Marker = false;
      if (Send_Led){
        SendLED(SerialInChr);
      }
    }
    if (Recieve_led){
      //nog implementeren!!
      // SendLED(SerialInChr);
    }
    if (Send_An){
      SendAnalog(AnalogOutChr1, AnalogOutChr2);
      Send_An = false;
    }

    if (Start_Tone){
      tone(SpeakerPin, 1915,100);//laag
      delay(100);
      noTone(SpeakerPin);
      Start_Tone = false;
    }
    
    ReadAndSendInput();
    
    if (Detect_Voice) {
      ReadValue = ReadAnalogChannel(4);
      if (ReadValue < sensorValue_low_Voice) {
        Serial.print(char(86));
        Detect_Voice = false;
      }
      if  (ReadValue > sensorValue_high_Voice) { 
        Serial.print(char(86));
        Detect_Voice = false;
      }
    } 

    if (Detect_Sound) {
      ReadValue = ReadAnalogChannel(1);
      if  (ReadValue > (sensorValue_high_Sound + treshold_Sound)) { 
        //SendOutput( 255 );
        Serial.print(char(83));
        Detect_Sound = false;
        //SendOutput( 0 );
      }
    } 
   
    //TimeNow2 = micros() - TimeNow2;
    //Serial.println(TimeNow2);
  }
}


//########SUBROUTINES##########################################

void InPortInputMode(){
  for (int pin=0; pin<8; pin++) {
    pinMode(I[pin], INPUT); // send 1
    digitalWriteFast2(I[pin], HIGH); 
  }
}

void SendOutput( byte Mark1 ) {    
  digitalWriteFast2(ShiftOutput,LOW);
  SPI.transfer(Mark1);
  digitalWriteFast2(ShiftOutput,HIGH);
}

void SendLED( byte Mark1 ) {    
  digitalWriteFast2(ShiftLED,LOW);
  SPI.transfer(Mark1);
  digitalWriteFast2(ShiftLED,HIGH);
}

void ReadAndSendInput() {     
  /* 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.
   */

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

      /* start debouncing */
      TimeOnSet_I[index] = TimeNow;
      Debouncing_I[index] = true;

      /* save new previous bit state */
      Prev_State_I[index] = State_I[index];
    }
  }

  /* reset debouncing status for each bit if the debounce interval has elapsed */
  for (index = 0; index < 8; index = index + 1) {
    if (Debouncing_I[index] & ((TimeNow - TimeOnSet_I[index]) > TimeoutDebounce)) {
      Debouncing_I[index] = false;
    }
  }
}

void Callibrate_Voice(){
  sensorValue_low_Voice = 1500;         // the sensor value
  sensorValue_high_Voice = 0;         // the sensor value
  for (int i=0; i <= 1200; i++){
    ReadValue = ReadAnalogChannel(4);
    if (ReadValue < sensorValue_low_Voice) {
      sensorValue_low_Voice = ReadValue;
    }
    if  (ReadValue > sensorValue_high_Voice) { 
      sensorValue_high_Voice = ReadValue;
    }
  } 
  sensorValue_low_Voice = sensorValue_low_Voice - treshold_Voice;
  sensorValue_high_Voice = sensorValue_high_Voice + treshold_Voice;
}

void Callibrate_Sound(){
  sensorValue_high_Sound = 0;         // the sensor value
  ReadValue = ReadAnalogChannel(1);
  ReadValue = ReadAnalogChannel(1);
  for (int i=0; i <= 2400; i++){
    ReadValue = ReadAnalogChannel(1);
    if  (ReadValue > sensorValue_high_Sound) { 
      sensorValue_high_Sound = ReadValue;
    }
  } 
}

/*void VoiceKey() {
  ReadValue = ReadAnalogChannel(4);
  if (ReadValue > (sensorValue_high_Voice)){
    nosound = 0;
  }
  else if (ReadValue < (sensorValue_low_Voice)) {
    nosound = 0;
  } 
  else {
    nosound = nosound + 1;
  }
  if ((detect_Voice) && (nosound == 0)){
    detect_Voice = false;
    Serial.write("V");
  }
  if (nosound == 1100){
    //OutPortWrite(0);
    Serial.write("v");
    detect_Voice = true;
    //Serial.print(128,DEC);
  }
}*/

int ReadAnalogChannel(int channel){
  SPI.end();
  pinMode(DATAIN, INPUT);
  pinMode(DATAOUT, OUTPUT);
  pinMode(SPICLOCK, OUTPUT);
  int adcvalue = 0;
  byte commandbits = B11000000; //command bits - start, mode, chn (3), dont care (3)

  //allow channel selection
  commandbits|=((channel-1)<<3);

  digitalWriteFast2(ShiftAnalogIn,LOW); //Select adc
  // setup bits to be written
  for (int i=7; i>=3; i--){
    digitalWriteFast2(DATAOUT,commandbits&1<<i);
    //cycle clock
    digitalWriteFast2(SPICLOCK,HIGH);
    digitalWriteFast2(SPICLOCK,LOW);    
  }

  digitalWriteFast2(SPICLOCK,HIGH);    //ignores 2 null bits
  digitalWriteFast2(SPICLOCK,LOW);
  digitalWriteFast2(SPICLOCK,HIGH);  
  digitalWriteFast2(SPICLOCK,LOW);

  //read bits from adc
  for (int i=11; i>=0; i--){
    adcvalue+=digitalReadFast2(DATAIN)<<i;
    //cycle clock
    digitalWriteFast2(SPICLOCK,HIGH);
    digitalWriteFast2(SPICLOCK,LOW);
  }
  digitalWriteFast2(ShiftAnalogIn, HIGH); //turn off device
  SPI.begin();
  //adcvalue = adcvalue >> 4;
  return adcvalue;
}
/*
int ReadAnalogChannel(int channel) {    
  //digitalWriteFast2(ShiftAnalogIn, LOW);      // select the MCP3204
  byte commandbits = B00001101;          //command bits - 0000, start, mode, chn, MSBF
  unsigned int b1 = 0;                   // get the return var's ready
  unsigned int b2 = 0;
  commandbits|=((channel-1)<<1);         // update the command bit to select either ch 1 or 2
  digitalWrite(ShiftAnalogIn, LOW);      // select the MCP3204
  SPI.transfer(commandbits);             // send out the command bits
  const int hi = SPI.transfer(b1);       // read back the result high byte
  const int lo = SPI.transfer(b2);       // then the low byte
  digitalWrite(ShiftAnalogIn, HIGH);     // let the DAC go, we'done
  b1 = lo + (hi << 8);                   // assemble the two bytes into a word
  b1 = b1 >> 4;
  return (b1);                      // We have got a 12bit answer but strip LSB's if
}
*/

void SendAnalog( byte analog1, byte analog2) {    
  digitalWriteFast2(ShiftAnalogOut,LOW);
  SPI.transfer(analog1);
  SPI.transfer(analog2);
  digitalWriteFast2(ShiftAnalogOut,HIGH);
}