framework optimised

framework optimised

--- task6/task6.ino
+++ task6/task6.ino
@@ -1,3 +1,5 @@
+
+
 //this is the main code for task 6 MSRD project
 //created on 4th Oct.
 //Created by Yuhan Long
@@ -5,12 +7,16 @@
 //all right reserved
 #include <TimerOne.h>
 #include <stdlib.h>
-#include "Task6Drivers.h"
-
+#include <Task6Drivers.h>
+#include <Servo.h>
+#include <Encoder.h>
+#include "Arduino.h"
 //int BUTTON=;
 //int SLOT=;

-
+Task6Drivers drivers;
+Servo servo;
+Encoder encoder(ENCODER_A,ENCODER_B);

 char time200 = 0;
 //public char time4 = 0;
@@ -34,6 +40,20 @@
 char CharReceived = 0;
 int ValReceived=0;

+
+
+void setup(){
+ //for setup code of pins and interrupts.
+ Timer1.initialize(5000);//set the timer interrupt at 5ms
+ Timer1.attachInterrupt(timerInterrupt);
+ Serial.begin(115200);
+ drivers.init();
+ //pinMode(BUTTON, INPUT);
+ //pinMode(SLOT, INPUT);
+
+ //set other output
+}
+
 void timerInterrupt(){
   //read switch at a granulartiy of 0.02s
   //take serial communication every 0.1s
@@ -41,116 +61,123 @@
   Serialdelay++;
   timer_count++;
   if(timer_count % 4 ==0){
-    ButtonBuf = ButtonBuf*2 + isPushedButton();
+    ButtonBuf = ButtonBuf*2 + drivers.isPushedButton();
     if (ButtonBuf==15){
         buttonPush = 1;
       }
     }

-  if(timer_count ==200) {
+  if(timer_count ==50) {
     //0.1 secound reached
     time200 = 1;
     timer_count = 0;
     }
 }
-
-void setup(){
- //for setup code of pins and interrupts.
- Timer1.initialize(5000);//set the timer interrupt at 100ms
- Timer1.attachInterrupt(timerInterrupt);
- Serial.begin(9600);
-
- //pinMode(BUTTON, INPUT);
- //pinMode(SLOT, INPUT);
-
- //set other output
-}
-
-void sendData(){
-  //send IR distance to computer
-  Serial.write("I");
-  Serial.write(irValue);
-  Serial.print("\n");
-  //send Sonor distance to computer
-  Serial.write("X");
-  Serial.write(sonicValue);
-  Serial.print("\n");
-  //send encoder Value
-  Serial.write("W");
-  Serial.write(encoderSpeed);
-  Serial.print("\n");
-  //send button state
-  Serial.write("B");
-  Serial.write(buttonValue);
-  Serial.print("\n");
-  //send slotswitch state
-  Serial.write("S");
-  Serial.write(slotValue);
-  Serial.print("\n");
-}
+//void sendData(){
+//  //send IR distance to computer
+//  Serial.write("I");
+//  Serial.println(100);
+//  //Serial.write(irValue);
+//  //send Sonor distance to computer
+//  Serial.write("X");
+//  Serial.println(100);
+// // Serial.write(sonicValue);
+//  //send encoder Value
+//  Serial.write("W");
+//  Serial.println(100);
+// // Serial.write(encoderSpeed);
+//  //Serial.print("\n");
+//  //send button state
+//  Serial.write("B");
+//  Serial.println(1);
+// // Serial.write(buttonValue);
+//  //send slotswitch state
+//  Serial.write("S");
+//  Serial.println(1);
+// // Serial.write(slotValue);
+//}

 void readSensor(){
   //receive IR distence
-  irValue= getIRDistance_mm();
+  irValue= drivers.getIRDistance_mm();
+  //Serial.write("I");
+  //Serial.println(100);
   //receive ultrasonic distance
-  sonicValue = getSonicDistance_mm();
+  sonicValue = drivers.getSonicDistance_mm();
+ // Serial.write("X");
+ // Serial.println(100);
   //receive encoder data
-  encoderSpeed = getDCSpeed_rpm();
+  encoderSpeed = drivers.getDCSpeed_rpm();
+ // Serial.write("W");
+ // Serial.println(100);
   //read button state
   buttonValue = buttonPush;
   buttonPush = 0;
-
+  //Serial.write("B");
+ // Serial.println(1);
+  slotValue = drivers.isTriggeredSlot();
+  //Serial.write("S");
+  //Serial.println(1);

   //read slotswitch state
-  slotValue = isTriggeredSlot();
 }

 void loop(){
   //read the serial input and report data to the server.
-  if(time200 == 1){
+  //if(time200 == 1){
     readSensor();
-    sendData();
+    //sendData();
     time200 = 0;
-    }
-  //Check serial port
+    //}
+//  //Check serial port
   int len = Serial.available();
   if ((Serial.available() >0 )&&(SerialState == 0)) {                             //when the serial input is ready
-    CharReceived=Serial.read();                                                   //read the character
-    if ((CharReceived == 'a' )||(CharReceived == 'w') ||(CharReceived == 's')||('p')) {  //if it is in the char list, transist the serial state into 1, reset the delay signal
-      SerialState = 1;
-      Serialdelay=0;
-    }
-  }
+    CharReceived=Serial.read();
+    //read the character
+
+    if ((CharReceived == 'a' )||(CharReceived == 'w') ||(CharReceived == 's')||(CharReceived =='p')) {
+      //if it is in the char list, transist the serial state into 1, reset the delay signal
+      ValReceived = Serial.parseInt();
+         switch(CharReceived){
+          case 'a': drivers.setServoAngle(ValReceived); Serial.print("a");Serial.print(ValReceived); break;                                //apply the command on motor
+          case 'w': drivers.setDCSpeed(ValReceived);dcWorkingState=0;Serial.print("w");Serial.print(ValReceived);break;
+          case 'p': dcWorkingState=1;Serial.print("p");Serial.print(ValReceived);break;
+          case 's': drivers.setStepperAngle(ValReceived);Serial.print("s");Serial.print(ValReceived);break;
+          }
+      //SerialState = 1;
+      //Serialdelay=0;
+     }
+   }

-
-  if ((SerialState ==1) && (Serialdelay>1))                                          //if already receive a letter, and 5ms passed
-    {
-    if (Serial.available() > 0) {
-      ValReceived = Serial.parseInt();
-
-      Serial.print(ValReceived);
-        switch(CharReceived){
-          case 'a': setServoAngle(ValReceived);break;                                //apply the command on motor
-          case 'w': setDCSpeed(ValReceived);dcWorkingState=0;break;
-          case 'p': dcWorkingState=1;break;
-          case 's': setStepperAngle(ValReceived);break;
-          }
-        SerialState = 0;                                                              //transist back to receiving letters
-      }
-      else                                                                               //anything else are garbage, return letter polling
-      {
-      SerialState=0;
-      }
-    }
+//
+//  if (SerialState ==1)                                          //if already receive a letter, and 5ms passed
+//    {
+//    if (Serial.available() > 0) {
+//      ValReceived = Serial.parseInt();
+//
+//      Serial.print(ValReceived);
+//        switch(CharReceived){
+//          case 'a': drivers.setServoAngle(ValReceived); Serial.print("a");Serial.print(ValReceived); break;                                //apply the command on motor
+//          case 'w': drivers.setDCSpeed(ValReceived);dcWorkingState=0;Serial.print("w");Serial.print(ValReceived);break;
+//          case 'p': dcWorkingState=1;Serial.print("p");Serial.print(ValReceived);break;
+//          case 's': drivers.setStepperAngle(ValReceived);Serial.print("s");Serial.print(ValReceived);break;
+//          }
+//        SerialState = 0;                                                              //transist back to receiving letters
+//      }
+//      else                                                                               //anything else are garbage, return letter polling
+//      {
+//      SerialState=0;
+//      }
+//    }

   //check dc working state
   //0 for set speed, 1 for set angle
   if(dcWorkingState == 0) {
-    actuateDC();
+    drivers.actuateDC();
     }
     else{
-    turnDC();
+    drivers.turnDC();
     }

 }


Fix esp32 TCP connection by skipping verification

This turns off certificate and/or fingerprint verification

--- examples/ESP32DevelopmentBoardSecure/ESP32DevelopmentBoardSecure.ino
+++ examples/ESP32DevelopmentBoardSecure/ESP32DevelopmentBoardSecure.ino
@@ -26,6 +26,7 @@
   }

   Serial.print("\nconnecting...");
+  net.setInsecure();
   while (!client.connect("arduino", "public", "public")) {
     Serial.print(".");
     delay(1000);


Use PWM

Use PWM

--- receiver_analog/receiver_analog.ino
+++ receiver_analog/receiver_analog.ino
@@ -9,15 +9,15 @@
 #include <VirtualWire.h>

 // inslude the SPI library:
-#include <SPI.h>
+//#include <SPI.h>

 #define DEBUG_LED_PIN 5 // PD5 (11) - Red led button
 #define DEBUG_LED_PWM_AWAKE 127 // pwm value to show contoller is awake
 #define DEBUG_LED_PWM_MSG 255 // pwm value to show message received

-//#define PWM_PIN 9 // TMP until dedicated chip arrives
-#define POT_CHIP_SELECT 10
-#define POT_ADDRESS 0
+#define PWM_PIN 11 // timer 2
+//#define POT_CHIP_SELECT 10
+//#define POT_ADDRESS 0

 #define VW_MAX_MESSAGE_LEN 40 // Same as solar/sensor
 #define VW_RX_PIN 7 // PD7 (13)
@@ -26,7 +26,7 @@
 #define WD_DO_STUFF 8 // How many watchdog interupts before doing real work (same a sensor).

-
+byte sleep_mode = SLEEP_MODE_PWR_SAVE;
 int parsed_val = 0;
 byte solar_val = 64; // Temporary half value
 volatile byte wd_isr = WD_DO_STUFF;
@@ -41,7 +41,7 @@
   } else {
       --wd_isr;
       // Go back to sleep.
-      goToSleep();
+      goToSleep(sleep_mode);
   }
 }

@@ -53,6 +53,9 @@
   // disable analog comparitor
   ACSR = (1 << ACD) | (0 << ACIE);

+  power_spi_disable();
+  power_twi_disable();
+
   watchdog_setup();

   pinMode(DEBUG_LED_PIN, OUTPUT);
@@ -62,12 +65,12 @@
   digitalWrite(RF_POWER_PIN, HIGH);

   // set the slaveSelectPin as an output:
-  pinMode (POT_CHIP_SELECT, OUTPUT);
+  //pinMode (POT_CHIP_SELECT, OUTPUT);
   // initialize SPI:
-  SPI.begin();
-
-  //pinMode(PWM_PIN, OUTPUT);  // TMP until dedicated chip arrives
-  //analogWrite(PWM_PIN, solar_val);
+  //SPI.begin();
+
+  pinMode(PWM_PIN, OUTPUT);
+  analogWrite(PWM_PIN, 255);

   Serial.begin(9600);
   Serial.println("Setup");
@@ -76,7 +79,6 @@
   vw_setup(2000);	 // Bits per sec
   vw_rx_start();       // Start the receiver running

-  digitalPotWrite(POT_ADDRESS, 128);
 }

@@ -105,7 +107,7 @@

         if (comma == 5) {
           parsed_val = val;
-          solar_val = map(val, 0, 10000, 0, 128);
+          solar_val = map(val, 0, 10000, 0, 255);

           // Print the solar reading
@@ -150,15 +152,13 @@

     Serial.println();
-
-    // Ofcourse this is rather pointless a sleep will kill the pwm (replacing with digital pot)
-    //analogWrite(PWM_PIN, solar_val);
-
+
     Serial.print(parsed_val);
     Serial.print(" -> ");
     Serial.println(solar_val);

-    digitalPotWrite(POT_ADDRESS, solar_val);
+    //digitalPotWrite(POT_ADDRESS, solar_val);
+    analogWrite(PWM_PIN, solar_val);

     // Turn off message indicator
     analogWrite(DEBUG_LED_PIN, DEBUG_LED_PWM_AWAKE);
@@ -167,11 +167,17 @@
     Serial.flush();

     // Sleep 'till the next message is due
-    goToSleep();
+    if (solar_val > 0) {
+      goToSleep(SLEEP_MODE_PWR_SAVE);
+    } else {
+      // no need for pwm so full sleep
+      goToSleep(SLEEP_MODE_PWR_DOWN);
+    }
   }

 }

+/*
 void digitalPotWrite(int address, int value) {
   // take the SS pin low to select the chip:
   digitalWrite(POT_CHIP_SELECT, LOW);
@@ -181,6 +187,7 @@
   // take the SS pin high to de-select the chip:
   digitalWrite(POT_CHIP_SELECT, HIGH);
 }
+*/

 /**
  * Watchdog for while awake to ensure things are ticking over.
@@ -207,9 +214,10 @@
   wdt_reset();
 }

-void goToSleep()
-{
-
+void goToSleep(byte mode)
+{
+  sleep_mode = mode;
+
   // Turn off the RF receiver
   digitalWrite(RF_POWER_PIN, LOW);

@@ -217,13 +225,22 @@
   digitalWrite(DEBUG_LED_PIN, LOW);

   cli();
-
+
   // ensure ADC is off
   ADCSRA = 0;

-  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
-  power_all_disable();
-
+  if (mode == SLEEP_MODE_PWR_DOWN) {
+    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+    power_all_disable();
+  } else {
+    // Keep pwm on
+    set_sleep_mode(SLEEP_MODE_PWR_SAVE);
+    power_timer0_disable();
+    power_timer1_disable();
+    power_usart0_disable();
+    // leaving timer2 on for the pwm
+  }
+
   sleep_enable();
   sei();

@@ -235,7 +252,9 @@
   sleep_disable();
   MCUSR = 0; // clear the reset register

-  power_all_enable();
+  power_timer0_enable();
+  power_timer1_enable();
+  power_usart0_enable();

   // turn on the RF receiver
   digitalWrite(RF_POWER_PIN, HIGH);


Changed mailbox api to be just how the user presses

--- dayrider/dayrider.ino
+++ dayrider/dayrider.ino
@@ -9,14 +9,14 @@
 Dagu4Motor right(3, 2, 0, 0, 0);

 void setup() {
-  Serial.begin(9600);
+  //Serial.begin(9600);
   pinMode(13,OUTPUT);
   digitalWrite(13, LOW);
   Bridge.begin();
   Mailbox.begin();
   digitalWrite(13, HIGH);

-  Serial.println("Starting Dayrider 0.1");
+  //Serial.println("Starting Dayrider 0.1");

   left.begin();
   left.stopMotors();
@@ -25,31 +25,98 @@

 void loop() {
   if (Mailbox.messageAvailable()) {
-    process_mb();
+    process_cmd();
   }

   delay(50);
 }

-void process_mb() {
-  int start, end, dir, spd;
-  String msg, side, tmp;
+#define LEFT 1
+#define RIGHT 2
+#define FORWARD 3
+#define BACKWARD 4
+
+#define MOTOR_FORWARD 0
+#define MOTOR_BACKWARD 1
+
+#define MOTOR_SPEED 150
+
+int current_direction = 0;
+
+void process_cmd() {
+  String cmd;

-  Mailbox.readMessage(msg);
+  Mailbox.readMessage(cmd);
+  if (cmd == "left") {
+    turn_left();
+  } else if (cmd == "right") {
+    turn_right();
+  } else if (cmd == "forward") {
+    go_forward();
+  } else if (cmd == "backward") {
+    go_backwards();
+  }

-  Serial.println(msg);
+  //Serial.println(cmd);

-  end = msg.indexOf('/');
-  side = msg.substring(0, end);
-  start = end+1;
-  end = msg.indexOf('/', start);
-  dir = msg.substring(start, end).toInt();
-  start = end+1;
-  spd = msg.substring(start).toInt();
-
-  motorCommand(side, dir, spd);
 }

+void turn_left() {
+     if (current_direction == RIGHT) {
+        stop_movement();
+        current_direction = 0;
+        return;
+     }
+     left.setMotorDirection(MOTOR_FORWARD);
+     left.setSpeed(MOTOR_SPEED);
+     //right.setMotorDirection(MOTOR_BACKWARD);
+     //right.setSpeed(MOTOR_SPEED / 2);
+     current_direction = LEFT;
+}
+
+void turn_right() {
+     if (current_direction == LEFT) {
+        stop_movement();
+        current_direction = 0;
+        return;
+     }
+     //right.setMotorDirection(MOTOR_FORWARD);
+     //right.setSpeed(MOTOR_SPEED);
+     left.setMotorDirection(MOTOR_BACKWARD);
+     left.setSpeed(MOTOR_SPEED / 2);
+     current_direction = RIGHT;
+}
+
+void go_forward() {
+     if (current_direction == BACKWARD) {
+        stop_movement();
+        current_direction = 0;
+        return;
+     }
+     //right.setMotorDirection(MOTOR_FORWARD);
+     //right.setSpeed(MOTOR_SPEED);
+     left.setMotorDirection(MOTOR_FORWARD);
+     left.setSpeed(MOTOR_SPEED);
+     current_direction = FORWARD;
+}
+
+void go_backwards() {
+     if (current_direction == FORWARD) {
+        stop_movement();
+        current_direction = 0;
+        return;
+     }
+     //right.setMotorDirection(MOTOR_BACKWARD);
+     //right.setSpeed(MOTOR_SPEED);
+     left.setMotorDirection(MOTOR_BACKWARD);
+     left.setSpeed(MOTOR_SPEED);
+     current_direction = BACKWARD;
+}
+
+void stop_movement() {
+     //right.setSpeed(0);
+     left.setSpeed(0);
+}

 void motorCommand(String side, int dir, int spd) {


Updated idle screen

Updated idle screen

--- Sakuya_TiLDA/Sakuya_TiLDA.ino
+++ Sakuya_TiLDA/Sakuya_TiLDA.ino
@@ -68,9 +68,7 @@
   // Display some text on the GLCD
   tilda.glcd.firstPage();
   do
-  {
-    draw();
-  }
+    glcd_draw();
   while(tilda.glcd.nextPage());
 }

@@ -411,7 +409,7 @@
   return true;
 }

-void draw()
+void glcd_draw()
 {
   switch(display)
   {
@@ -430,8 +428,13 @@
  */
 void draw_idle()
 {
-  //TODO
   tilda.glcd.drawBitmapP(0, 0, 8, 64, sakuya_1_bitmap);
+
+  tilda.glcd.setFont(u8g_font_helvR12);
+
+  tilda.glcd.drawStr(80, 22, "No");
+  tilda.glcd.drawStr(75, 37, "New");
+  tilda.glcd.drawStr(70, 52, "Alerts");
 }

 /**


Delete MPU9150.ino

Delete MPU9150.ino

--- software/IMU_Compass/MPU9150.ino
+++ software/IMU_Compass/MPU9150.ino
@@ -1,5 +0,0 @@
-void MPU9150_init(void)
-{
- // todo
-}
-


Changed pin numbers to match with arduino mega.

--- tests/drive-test/Chassis_Control/Chassis_Control.ino
+++ tests/drive-test/Chassis_Control/Chassis_Control.ino
@@ -18,7 +18,7 @@
 #define TIMEOUT 1000
 #endif

-const int TALON_LEFT = 13, TALON_RIGHT = 14, MIN_FREQUENCY = 1002, MAX_FREQUENCY = 2041;
+const int TALON_LEFT = 12, TALON_RIGHT = 13, MIN_FREQUENCY = 1002, MAX_FREQUENCY = 2041;
 unsigned long timeLastPacket;

 Servo leftMotor, rightMotor;


Leakage timer overflow fix

Leakage timer overflow fix

--- Arduino/_firmware3/_firmware3.ino
+++ Arduino/_firmware3/_firmware3.ino
@@ -31,7 +31,7 @@
 //+3.3V Fluid Leve
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //                                            Analog smoothing
-const int number_of_readings = 30; //Increases the size of global variables big time. Can be be managed in case we run into memory issues
+const int number_of_readings = 25; //Increases the size of global variables big time. Can be be managed in case we run into memory issues
 int analog_index = 0;

 float smoothing(const int* numb_readings, float* total_sum,
@@ -167,7 +167,7 @@
    }

-  //Calculate the flow rate
+  //Calculate the flow ratecal
    if (solenoid_valve_open == false){
     if (water_level_cm >= (flow_calc_water_level_cm + water_level_buffer)){
       //Serial.println("CALCULATION TRIGGERED!");
@@ -192,6 +192,8 @@
       calc_time_ms = millis();
     }
    }
+
+   if (calc_time_ms > millis()) calc_time_ms = millis(); // to Reset the timer variable once millis() timer overflows.

     if (solenoid_valve_open == true && water_level_cm <= close_valve_at_cm_level){
     digitalWrite(solenoidValvePin,LOW);
@@ -309,7 +311,7 @@
       do{
         PinState = digitalRead(ClockPin);
         if ((millis() - time_check) >= 2000){//Haha, let's NOT get stuck if the thing is unplugged
-          Serial.println("ir_cl_sync_error");
+          //Serial.println("ir_cl_sync_error");
           break;
         }
         //Serial.println("hh");
@@ -325,7 +327,7 @@
         PinState = digitalRead(ClockPin);  //get stuck until clock changes

         if ((millis() - time_check) >= 2000){//Haha, let's NOT get stuck if the thing is unplugged
-          Serial.println("ir_cl_sync_error");
+          //Serial.println("ir_cl_sync_error");
           break;
         }
       }while(PinState != 1);
@@ -346,7 +348,7 @@
       data_read(data_buf);
       delay(1);
       if ((millis() - time_check) >= 2000){//Haha, let's NOT get stuck if the thing is unplugged
-        Serial.println("checksum_error");
+        //Serial.println("checksum_error");
         break;
         }

@@ -609,7 +611,7 @@

     rpm_calculation();
     flow_rate();
-    //shaft_temp();
+    shaft_temp();
     one_wire_temps();
     Irms = emon1.calcIrms(1480);  // Calculate Irms only
     if (Irms < 2) Irms = 0;//Until library is fixed


looks not so bad

looks not so bad

--- slave_receiver/slave_receiver.ino
+++ slave_receiver/slave_receiver.ino
@@ -9,7 +9,6 @@
 double amp2;   // amplitude of the second stimulus
 int wave;   // waveform
 int x;
-int pause_t = 0;

 int f_new;
 int num_samples = 100000;
@@ -17,11 +16,15 @@
 int j = 0;
 int k = 0;
 int l = 0;
+int duration, pause_t;
 char data_string[6][6];
-int data[50];
+char data[50];
 int indices[6];
+String test;
+String f_new_s, amp1_s, amp2_s, duration_s, pause_t_s;

-bool received_data;
+
+bool received_data = false;

 // table of data send by Matlab through the first arduino
@@ -43,47 +46,56 @@
   Wire.begin(1);                // join i2c bus with address #4
   Wire.onReceive(receiveEvent); // register event
   Serial.begin(57600);           // start serial for output
+
 }

 void loop()
 {
   delay(100);
     if(received_data){
-
-  f_new = atoi(data_string[0]);
-  Serial.println(f_new);
-  amp1 = atof(data_string[2]);
+   Serial.println("So weit, so gut");
+   for(i=0;i<50;i++){
+   test += data[i];}
+  // Serial.print(test);
+   f_new_s = test.substring(1,indices[0]);
+   f_new = f_new_s.toInt();
+  amp1_s = test.substring(indices[0]+1,indices[1]);
+  amp1 = amp1_s.toFloat();
+  amp2_s = test.substring(indices[1]+1, indices[2]);
+  amp2 = amp2_s.toFloat();
+  duration_s = test.substring(indices[2]+1,indices[3]);
+  duration = duration_s.toInt();
+  pause_t_s = test.substring(indices[3]+1,indices[4]);
+  pause_t =  pause_t_s.toInt();
   Timer1.start();
-  delayMicroseconds(atoi(data_string[4]));
+  delayMicroseconds(duration);
   Timer1.stop();
-  delayMicroseconds(atoi(data_string[5]));
+  delayMicroseconds(pause_t);
   f_new = atoi(data_string[1]);
   amp2 = atof(data_string[3]);
   Timer2.start();
-  delayMicroseconds(atoi(data_string[4]));
+  delayMicroseconds(duration);
   Timer2.stop();
-  received_data =  false;}
+  received_data =  false;
+  j = 0;
+}
 }

 // function that executes whenever data is received from master
 // this function is registered as an event, see setup()
 void receiveEvent(int howMany)
 {
-  int x = Wire.read();    // receive byte as an integer
-  Serial.println(x);         // print the integer
-  data[j] = x;
   j++;
-  if(j > 2 && data[j] == 110 & data[j-1] == 92){
-    indices[k] = j;
-    Serial.println(j);
+  data[j] = Wire.read();    // receive byte as a char
+
+  if(data[j] == 'n'){
+    indices[k] = j-2;
     k++;
-    if(k>0){
-    for(l = indices[k-1]; l = indices[k]; l++){
-      data_string[k][l] = data[l];}
+    if(k == 6){
+    received_data = true;
   }}
-    if(j > 2 && data[j] == 116 & data[j-1] == 92 ){
-  received_data = true;
-  Serial.println("Valid Test");
-  j = 0;}
+
+

 }
+


Base64 encoded image packets

Base64 encoded image packets

--- arduino_head/arduino_head.ino
+++ arduino_head/arduino_head.ino
@@ -4,16 +4,15 @@
 #include "ov2640_regs.h"

 //#define HOSTCONN
-//#if defined HOSTCONN
-//#include <AltSoftSerial.h>
+//#include <AltSoftSerial.h>  // Uncomment all three lines to enable software serial debugger (bug in IDE)
 //AltSoftSerial SWserial;
-//#endif

 void handle_host ();
 void xlog (char * origin, char * text);
 void xlognum (char * origin, char * text, int number);
 void w_handle_line ();
 void rsend (char * msg);
+void send_image_packet();

 void state_0_1 ();
 void state_1_2 ();
@@ -39,9 +38,9 @@
 void setup()
 {
     Serial.begin(115200);  // ESP8266
-//#if defined HOSTCONN
-//    SWserial.begin(9600);  // Host connection/log
-//#endif
+#if defined HOSTCONN
+    SWserial.begin(9600);  // Host connection/log
+#endif
     xlog ("H", "starting");
     pinMode(2, OUTPUT);
 }
@@ -118,81 +117,136 @@
       }

       if (capture == 2) {
-        xlognum ("H","packet",imglen);
-        uint8_t temp, temp_last;
-        uint32_t len = imglen;
-        int found_end = 0;
-        if (len > 1024) len = 1024; // Cap this at 1k at a time.
-        Serial.print ("AT+CIPSEND=0,");
-        Serial.print (len+7);
-        Serial.print ("\r\n");
-        delay(10);
-        Serial.print ("+img:");
-
-        while (len) {
-          imglen--;
-          temp_last = temp;
-          temp = SPI.transfer(0x00);
-          Serial.write(temp);
-          if ((temp == 0xD9) && (temp_last == 0xFF)) break;
-          delayMicroseconds(12);
-          len--;
+        send_image_packet();
+      }
+    }
+}
+
+// Base64 encoder adapted from https://github.com/adamvr/arduino-base64
+void base64_write(char * a3, int *i, int ch);
+void base64_write_end(char * a3, int *i);
+const char PROGMEM b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+      	                            "abcdefghijklmnopqrstuvwxyz"
+                                    "0123456789+/";
+
+void send_image_packet() {
+    xlognum ("H","packet",imglen);
+    uint8_t temp, temp_last;
+
+    char a3[3];
+    int i = 0;
+    int found_end = 0;
+
+    uint32_t len = imglen;
+    if (len > 1024) len = 1024; // Cap this at 1k at a time.
+
+    Serial.print ("AT+CIPSEND=0,");
+    Serial.print (((len+2)/3)*4+9);  // Break our packet into chunks of 3 bytes, base64-encode to 4-byte chunks.
+    Serial.print ("\r\n");
+    delay(10);
+    Serial.print ("+img:\r\n");
+
+    while (len) {
+      imglen--;
+      temp_last = temp;
+      temp = SPI.transfer(0x00);
+      base64_write (a3, &i, temp);
+      if ((temp == 0xD9) && (temp_last == 0xFF)) break;
+      delayMicroseconds(12);
+      len--;
+    }
+
+    if (len) {
+      xlognum ("H","imgend", len);
+      found_end = 1;
+      len--;
+      while (len--) { base64_write(a3, &i, 0x00); }
+    }
+    base64_write_end(a3, &i);
+
+    Serial.print ("\r\n");
+    xlog("H","done sending");
+    state = 8;
+
+    if (found_end || !imglen) {
+      xlog ("H","image done");
+      cam.CS_HIGH();
+      capture = 3; // Set state machine to send "done" after current packet is finished sending.
+    }
+}
+
+inline void a3_to_a4(char * a4, char * a3) {
+  a4[0] = (a3[0] & 0xfc) >> 2;
+  a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
+  a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
+  a4[3] = (a3[2] & 0x3f);
+}
+void base64_write (char *a3, int *i, int ch) {
+  a3[*i] = ch; *i += 1;
+  if (*i == 3) {
+    char a4[4];
+    a3_to_a4(a4, a3);
+    Serial.write(pgm_read_byte(&b64_alphabet[a3[0]]));
+    Serial.write(pgm_read_byte(&b64_alphabet[a3[1]]));
+    Serial.write(pgm_read_byte(&b64_alphabet[a3[2]]));
+    Serial.write(pgm_read_byte(&b64_alphabet[a3[3]]));
+    *i = 0;
+  }
+}
+void base64_write_end (char *a3, int *i) {
+  if (!*i) return;
+  int j;
+  char a4[4];
+  for (j=*i; j < 3; j++) {
+    a3[j] = '\0';
+  }
+  for (j=0; j < *i + 1; j++) {
+    Serial.write(pgm_read_byte(&b64_alphabet[a3[j]]));
+  }
+  while (*i < 3) {
+    Serial.write('=');
+    *i += 1;
+  }
+  *i=0;
+}
+
+void handle_host () {
+#ifdef HOSTCONN
+      if (SWserial.available() ) {
+      int char_in = SWserial.read();
+      switch (char_in) {
+        case '\n': break; // ignore linefeed
+        case '\r':
+           SWserial.print ("\n\r");
+           h_handle_line();
+           break;
+        default:
+           SWserial.write (char_in);  // Mirror to host for human consumption
+           hlinebuf[hlineoff++] = char_in;
+           if (hlineoff > 254) {
+              xlog("H", "line too long, ignoring");
+              hlineoff = 0;
+           }
         }
-        if (len) {
-          xlognum ("H","imgend", len);
-          found_end = 1;
-          len--;
-          while (len--) { Serial.write(0x00); }
-        }
-        Serial.print ("\r\n");
-        xlog("H","done sending");
-        state = 8;
-        if (found_end || !imglen) {
-          xlog ("H","image done");
-          cam.CS_HIGH();
-          capture = 3;
-        }
-      }
-    }
-}
-
-void handle_host () {
-//#ifdef HOSTCONN
-//      if (SWserial.available() ) {
-//      int char_in = SWserial.read();
-//      switch (char_in) {
-//        case '\n': break; // ignore linefeed
-//        case '\r':
-//           SWserial.print ("\n\r");
-//           h_handle_line();
-//           break;
-//        default:
-//           SWserial.write (char_in);  // Mirror to host for human consumption
-//           hlinebuf[hlineoff++] = char_in;
-//           if (hlineoff > 254) {
-//              xlog("H", "line too long, ignoring");
-//              hlineoff = 0;
- //          }
- //       }
- //     }
-//#endif
+      }
+#endif
 }

 void xlog (char * origin, char * text) {
-//#ifdef HOSTCONN
-//    SWserial.print (origin);
-//    SWserial.print (":");
-//    SWserial.println (text);
-//#endif
+#ifdef HOSTCONN
+    SWserial.print (origin);
+    SWserial.print (":");
+    SWserial.println (text);
+#endif
 }
 void xlognum (char * origin, char * text, int number) {
-//#ifdef HOSTCONN
-//    SWserial.print (origin);
-//    SWserial.print (":");
-//    SWserial.print (text);
-//    SWserial.print (" ");
-//    SWserial.println (number);
-//#endif
+#ifdef HOSTCONN
+    SWserial.print (origin);
+    SWserial.print (":");
+    SWserial.print (text);
+    SWserial.print (" ");
+    SWserial.println (number);
+#endif
 }

 void wsend (char * text) {


change if statement to switch statement.

--- duinoCar/duinoCar.ino
+++ duinoCar/duinoCar.ino
@@ -41,44 +41,51 @@

   if( Serial2.available()){
     char ch = Serial2.read();
-    if(ch == 'A'){
-      Serial2.println("34.41294,108.06941,00002000,131658,0.12,0.93");
-      ledAct();
-    }
-    else if(ch == 'B'){
-      Serial2.println("34.42345,108.07364,00002000,131660,0.34,10.12");
-      ledAct();
-    }
-    else if(ch == 'X'){
-      forward();
-      Serial2.println("Forward");
-      ledAct();
-    }
-    else if(ch == 'W'){
-      backward();
-      Serial2.println("Backward");
-      ledAct();
-    }
-    else if(ch == 'U' || ch == 'Z'){
-      Serial2.println("Turn left");
-      ledAct();
-    }
-    else if(ch == 'V' || ch == 'Y'){
-      Serial2.println("Turn right");
-      ledAct();
-    }
-    else if(ch == 'T'){
-      stopCar();
-      Serial2.println("STOP");
-      ledAct();
-    }
-    else if(ch == 'D'){
-      stopCar();
-      Serial2.println("Testing");
-      testState = true;
-      test();
-    }
-    else if(ch == 'C'){
+    switch(ch){
+      case 'A':
+        Serial2.println("34.41294,108.06941,00002000,131658,0.12,0.93");
+        ledAct();
+        break;
+      case 'B':
+        Serial2.println("34.42345,108.07364,00002000,131660,0.34,10.12");
+        ledAct();
+        break;
+      case 'X':
+        forward();
+        Serial2.println("Forward");
+        ledAct();
+        break;
+      case 'W':
+        backward();
+        Serial2.println("Backward");
+        ledAct();
+        break;
+      case 'U':
+        Serial2.println("Turn left");
+        ledAct();
+        break;
+      case 'Z':
+        Serial2.println("Turn left");
+        ledAct();
+        break;
+      case 'V':
+        Serial2.println("Turn right");
+        ledAct();
+        break;
+      case 'Y':
+        Serial2.println("Turn right");
+        ledAct();
+        break;
+      case 'T':
+        stopCar();
+        Serial2.println("STOP");
+        ledAct();
+        break;
+      case 'D':
+        stopCar();
+        Serial2.println("Testing");
+        testState = true;
+        test();
     }
   }
 }


Modified test sketch to use built-in random() function, and made it loop forever.

--- ecc_test/ecc_test.ino
+++ ecc_test/ecc_test.ino
@@ -15,19 +15,38 @@

 #include <ecc.h>

+extern "C" {
+
+static int RNG(uint8_t *p_dest, unsigned p_size)
+{
+  while(p_size) {
+    long v = random();
+    unsigned l_amount = min(p_size, sizeof(long));
+    memcpy(p_dest, &v, l_amount);
+    p_size -= l_amount;
+    p_dest += l_amount;
+  }
+  return 1;
+}
+
+}
+
 void setup() {
-    Scout.setup();
-    uint8_t l_private1[ECC_BYTES];
-    uint8_t l_private2[ECC_BYTES];
-
-    uint8_t l_public1[ECC_BYTES * 2];
-    uint8_t l_public2[ECC_BYTES * 2];
-
-    uint8_t l_secret1[ECC_BYTES];
-    uint8_t l_secret2[ECC_BYTES];
-
-    Serial.print("Testing ecc\n");
-
+  Scout.setup();
+  uint8_t l_private1[ECC_BYTES];
+  uint8_t l_private2[ECC_BYTES];
+
+  uint8_t l_public1[ECC_BYTES * 2];
+  uint8_t l_public2[ECC_BYTES * 2];
+
+  uint8_t l_secret1[ECC_BYTES];
+  uint8_t l_secret2[ECC_BYTES];
+
+  Serial.print("Testing ecc\n");
+
+  ecc_set_rng(&RNG);
+
+  for(;;) {
     unsigned long a = millis();
     ecc_make_key(l_public1, l_private1);
     unsigned long b = millis();
@@ -78,6 +97,7 @@
     {
         Serial.print("Shared secrets are identical\n");
     }
+  }
 }

 void loop() {


Example of sketch that uses default setup() and loop(). Pure OOP.

--- examples/Pins/CosaBlinkPeriodic/CosaBlinkPeriodic.ino
+++ examples/Pins/CosaBlinkPeriodic/CosaBlinkPeriodic.ino
@@ -50,11 +50,7 @@
 LED blueLedPin(Board::D7, 1024);
 #endif

+// Use the builtin led
 LED heartbeat(Board::LED, 512);

-// Start the watchdog (16 ms timeout, push timeout events)
-void setup()
-{
-  Watchdog::begin(16, SLEEP_MODE_IDLE, Watchdog::push_timeout_events);
-}
-
+// Thats all. No setup() or loop() function necessary. Use the default


resetAll() now stops the current note; formatting

--- Arduino/Moppy/Moppy.ino
+++ Arduino/Moppy/Moppy.ino
@@ -9,31 +9,31 @@

 /*NOTE: Many of the arrays below contain unused indexes.  This is
-to prevent the Arduino from having to convert a pin input to an alternate
-array index and save as many cycles as possible.  In other words information
-for pin 2 will be stored in index 2, and information for pin 4 will be
-stored in index 4.*/
+ to prevent the Arduino from having to convert a pin input to an alternate
+ array index and save as many cycles as possible.  In other words information
+ for pin 2 will be stored in index 2, and information for pin 4 will be
+ stored in index 4.*/

 /*An array of maximum track positions for each step-control pin.  Even pins
-are used for control, so only even numbers need a value here.  3.5" Floppies have
-80 tracks, 5.25" have 50.  These should be doubled, because each tick is now
-half a position (use 158 and 98).
-*/
+ are used for control, so only even numbers need a value here.  3.5" Floppies have
+ 80 tracks, 5.25" have 50.  These should be doubled, because each tick is now
+ half a position (use 158 and 98).
+ */
 byte MAX_POSITION[] = {
   0,0,158,0,158,0,158,0,158,0,158,0,158,0,158,0,158,0};
-
+
 //Array to track the current position of each floppy head.  (Only even indexes (i.e. 2,4,6...) are used)
 byte currentPosition[] = {
   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

 /*Array to keep track of state of each pin.  Even indexes track the control-pins for toggle purposes.  Odd indexes
-track direction-pins.  LOW = forward, HIGH=reverse
-*/
+ track direction-pins.  LOW = forward, HIGH=reverse
+ */
 int currentState[] = {
   0,0,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW
 };
-
+
 //Current period assigned to each pin.  0 = off.  Each period is of the length specified by the RESOLUTION
 //variable above.  i.e. A period of 10 is (RESOLUTION x 10) microseconds long.
 unsigned int currentPeriod[] = {
@@ -75,7 +75,7 @@

 void loop(){
-
+
   //The first loop, reset all the drives, and wait 2 seconds...
   if (firstRun)
   {
@@ -103,13 +103,13 @@

 /*
 Called by the timer inturrupt at the specified resolution.
-*/
+ */
 void tick()
 {
   /*
-  If there is a period set for control pin 2, count the number of
-  ticks that pass, and toggle the pin if the current period is reached.
-  */
+   If there is a period set for control pin 2, count the number of
+   ticks that pass, and toggle the pin if the current period is reached.
+   */
   if (currentPeriod[2]>0){
     currentTick[2]++;
     if (currentTick[2] >= currentPeriod[2]){
@@ -166,11 +166,11 @@
       currentTick[16]=0;
     }
   }
-
+
 }

 void togglePin(byte pin, byte direction_pin) {
-
+
   //Switch directions if end has been reached
   if (currentPosition[pin] >= MAX_POSITION[pin]) {
     currentState[direction_pin] = HIGH;
@@ -180,15 +180,15 @@
     currentState[direction_pin] = LOW;
     digitalWrite(direction_pin,LOW);
   }
-
-    //Update currentPosition
+
+  //Update currentPosition
   if (currentState[direction_pin] == HIGH){
     currentPosition[pin]--;
   }
   else {
     currentPosition[pin]++;
   }
-
+
   //Pulse the control pin
   digitalWrite(pin,currentState[pin]);
   currentState[pin] = ~currentState[pin];
@@ -222,12 +222,17 @@

 //Resets all the pins
 void resetAll(){
-
+
   // Old one-at-a-time reset
   //for (byte p=FIRST_PIN;p<=PIN_MAX;p+=2){
   //  reset(p);
   //}
-
+
+  //Stop all notes (don't want to be playing during/after reset)
+  for (byte p=FIRST_PIN;p<=PIN_MAX;p+=2){
+    currentPeriod[p] = 0; // Stop playing notes
+  }
+
   // New all-at-once reset
   for (byte s=0;s<80;s++){ // For max drive's position
     for (byte p=FIRST_PIN;p<=PIN_MAX;p+=2){
@@ -237,14 +242,11 @@
     }
     delay(5);
   }
-
+
   for (byte p=FIRST_PIN;p<=PIN_MAX;p+=2){
     currentPosition[p] = 0; // We're reset.
     digitalWrite(p+1,LOW);
     currentState[p+1] = 0; // Ready to go forward.
   }
-
-}
-
-
-
+
+}


Added better LCD screen status messages

Added better LCD screen status messages

--- FumeHoodMonitor/LCD.ino
+++ FumeHoodMonitor/LCD.ino
@@ -44,8 +44,13 @@
 }

 void writeLCD(String timeString, float ambientTemp, float fluidTemp, String flameStatus){
+  String statusMsg = "Error:";
+  if (onFire) statusMsg += " Fire";
+  if (airHigh) statusMsg += " Air";
+  if (oilHigh) statusMsg += " Oil";
+  if (!onFire && !airHigh && !oilHigh) statusMsg = timeString;
   lcd.setCursor(0,0);
-  lcd.print(make20Characters(timeString));
+  lcd.print(make20Characters(statusMsg));
   lcd.setCursor(0,1);
   lcd.print(make20Characters("Air Temp: " + String(ambientTemp, 2) + String((char)223) + "F"));
   lcd.setCursor(0,2);
@@ -67,7 +72,9 @@
 }

 String make20Characters(String str){
-  for (unsigned int i = 0; i < (20 - str.length()); i++) str += " ";
+  while (str.length() < 20) {
+    str += " ";
+  }
   return str;
 }


Add: more day colors

Add: more day colors


Fix default volume handling for legacy cards

--- RfidShelf/RfidShelf.ino
+++ RfidShelf/RfidShelf.ino
@@ -253,13 +253,11 @@

     if (readFolder[1] != '\0' && switchFolder(readFolder)) {
       uint8_t configBuffer[18];
-      if (readRfidBlock(2, 0, configBuffer, sizeof(configBuffer))) {
-        if(configBuffer[0] == 137) {
-          if(configBuffer[1] > 0) {
-            Serial.print(F("Setting volume: ")); Serial.println(configBuffer[2]);
-            volume = configBuffer[2];
-            musicPlayer.setVolume(volume, volume);
-          }
+      if (readRfidBlock(2, 0, configBuffer, sizeof(configBuffer)) && (configBuffer[0] == 137)) {
+        if(configBuffer[1] > 0) {
+          Serial.print(F("Setting volume: ")); Serial.println(configBuffer[2]);
+          volume = configBuffer[2];
+          musicPlayer.setVolume(volume, volume);
         }
       } else {
         volume = DEFAULT_VOLUME;


Make SmartLED Shield V4 pinout the default now that the shield is in wide release

--- AnimatedGIFs.ino
+++ AnimatedGIFs.ino
@@ -61,7 +61,7 @@

 /*
  * CONFIGURATION:
- *  - If you're using SmartLED Shield V4 (or above), uncomment the line that includes <SmartMatrixShieldV4.h>
+ *  - If you're not using SmartLED Shield V4 (or above), comment out the line that includes <SmartMatrixShieldV4.h>
  *  - update the "SmartMatrix configuration and memory allocation" section to match the width and height and other configuration of your display
  *  - Note for 128x32 and 64x64 displays with Teensy 3.2 - need to reduce RAM:
  *    set kRefreshDepth=24 and kDmaBufferRows=2 or set USB Type: "None" in Arduino,
@@ -73,7 +73,7 @@
  */

 #if defined (ARDUINO)
-//#include <SmartLEDShieldV4.h>  // uncomment this line for SmartLED Shield V4 (needs to be before #include <SmartMatrix3.h>)
+#include <SmartLEDShieldV4.h>  // comment out this line for if you're not using SmartLED Shield V4 hardware (this line needs to be before #include <SmartMatrix3.h>)
 #include <SmartMatrix3.h>
 #elif defined (SPARK)
 #include "application.h"


Reset commands before disconnecting/resetting

	Arduino now resets Inputs and sends Neutral Input data before **and** after doing arduinoReset(), arduinoDisconnect() PING timeout on calculatePing().

--- ps2_controller/ps2_controller.ino
+++ ps2_controller/ps2_controller.ino
@@ -411,6 +411,63 @@

 void arduinoDisconnect() {
   disconnectCalled = currentMillis;
+
+  //  Before disconnecting, we need to reset all Command status, and tell the computer they were reset
+  serial_rx_buffer_controller[0] = 0x01; //  Preamble
+  serial_rx_buffer_controller[1] = 0x00; //  SELECT, L3, R3, START, DUP, DRIGHT, DDOWN, DLEFT
+  serial_rx_buffer_controller[2] = 0x00; //  L2, R2, L1, R1, Triangle/Delta, Circle/O, Cross/X, Square
+  serial_rx_buffer_controller[3] = 0x7F; //  RX
+  serial_rx_buffer_controller[4] = 0x7F; //  RY
+  serial_rx_buffer_controller[5] = 0x7F; //  LX
+  serial_rx_buffer_controller[6] = 0x7F; //  LY
+  serial_rx_buffer_controller[7] = 0x00; //  Analog button (Used to change between Digital and Analog modes in older games), Buffer Array Element 7  //  All other bits in this Buffer Array Element are unused
+  serial_rx_buffer_controller[8] = 0x00; //  Unused
+  serial_rx_buffer_controller[9] = 0x00; //  Delay Byte 2
+  serial_rx_buffer_controller[10] = 0x00; // Delay Byte 1
+  serial_rx_buffer_controller[11] = 0x01; // Postamble
+
+  for (serial_rx_buffer_counter = 0; serial_rx_buffer_counter < sizeof(serial_rx_buffer); serial_rx_buffer_counter++) {
+    Serial.write(serial_rx_buffer_controller[serial_rx_buffer_counter]); //  This line writes the serial data back to the computer as a way to check if the Arduino isn't interpreting wrong values
+    serial_rx_buffer_inverted_controller[serial_rx_buffer_counter] = (255 - serial_rx_buffer_controller[serial_rx_buffer_counter]); //  Invert 0 to 255 and vice versa to make it easier to determine which commands to enable or not, and their values
+  }
+
+  //  First 8 buttons, Buffer Array Element 1
+  //  SELECT, L3, R3, START, DUP, DRIGHT, DDOWN, DLEFT
+  digitalWrite(commandArray[0], (serial_rx_buffer_inverted_controller[1] & B00000001));
+  digitalWrite(commandArray[1], (serial_rx_buffer_inverted_controller[1] & B00000010));
+  digitalWrite(commandArray[2], (serial_rx_buffer_inverted_controller[1] & B00000100));
+  digitalWrite(commandArray[3], (serial_rx_buffer_inverted_controller[1] & B00001000));
+  digitalWrite(commandArray[4], (serial_rx_buffer_inverted_controller[1] & B00010000));
+  digitalWrite(commandArray[5], (serial_rx_buffer_inverted_controller[1] & B00100000));
+  digitalWrite(commandArray[6], (serial_rx_buffer_inverted_controller[1] & B01000000));
+  digitalWrite(commandArray[7], (serial_rx_buffer_inverted_controller[1] & B10000000));
+
+  //  Second 8 buttons, Buffer Array Element 2
+  //  L2, R2, L1, R1, Triangle/Delta, Circle/O, Cross/X, Square
+  digitalWrite(commandArray[8], (serial_rx_buffer_inverted_controller[2] & B00000001));
+  digitalWrite(commandArray[9], (serial_rx_buffer_inverted_controller[2] & B00000010));
+  digitalWrite(commandArray[10], (serial_rx_buffer_inverted_controller[2] & B00000100));
+  digitalWrite(commandArray[11], (serial_rx_buffer_inverted_controller[2] & B00001000));
+  digitalWrite(commandArray[12], (serial_rx_buffer_inverted_controller[2] & B00010000));
+  digitalWrite(commandArray[13], (serial_rx_buffer_inverted_controller[2] & B00100000));
+  digitalWrite(commandArray[14], (serial_rx_buffer_inverted_controller[2] & B01000000));
+  digitalWrite(commandArray[15], (serial_rx_buffer_inverted_controller[2] & B10000000));
+
+  //  4 Axis, Buffer Array Elements 3, 4, 5, 6
+  //  RX, RY, LX, LY
+  analogWrite(commandArray[16], serial_rx_buffer_inverted_controller[3]);
+  analogWrite(commandArray[17], serial_rx_buffer_inverted_controller[4]);
+  analogWrite(commandArray[18], serial_rx_buffer_inverted_controller[5]);
+  analogWrite(commandArray[19], serial_rx_buffer_inverted_controller[6]);
+
+  //  Analog button (Used to change between Digital and Analog modes in older games), Buffer Array Element 7
+  //  All other bits in this Buffer Array Element are unused
+  digitalWrite(commandArray[20], (serial_rx_buffer_inverted_controller[7] & B00000001));
+
+  //  Buffer Array Element 8 is unused in this code, but is existing in case changes are needed
+  Serial.flush();
+
+  //  Tell the computer the connection is about to be closed
   serial_rx_buffer_disconnect[8] = (byte)((disconnectCalled & 0xFF));
   serial_rx_buffer_disconnect[7] = (byte)((disconnectCalled >> 8) & 0xFF);
   serial_rx_buffer_disconnect[6] = (byte)((disconnectCalled >> 16) & 0xFF);
@@ -418,7 +475,7 @@
   //Serial.println(disconnectCalled);
   //Serial.println("DISCONNECTING...");
   serial_rx_buffer_disconnect[0] = 0x0A;
-  serial_rx_buffer_disconnect[11] = 0x0A;
+  serial_rx_buffer_disconnect[11] = 0x0A;
   for (serial_rx_buffer_counter = 0; serial_rx_buffer_counter < sizeof(serial_rx_buffer_disconnect); serial_rx_buffer_counter++) {
     Serial.write(serial_rx_buffer_disconnect[serial_rx_buffer_counter]); //  This line writes the serial data back to the computer as a way to check if the Arduino isn't interpreting wrong values
   }
@@ -430,6 +487,7 @@
   serial_rx_buffer_disconnect[6] = (byte)((disconnectDone >> 16) & 0xFF);
   serial_rx_buffer_disconnect[5] = (byte)((disconnectDone >> 24) & 0xFF);
   delay(2500); // Wait 2.5 seconds before reconnecting
+  //  Tell the computer the connection has began succesfully
   isConnected = true;
   disconnectDone = currentMillis;
   Serial.begin(baudRate);
@@ -440,12 +498,125 @@
     Serial.write(serial_rx_buffer_disconnect[serial_rx_buffer_counter]); //  This line writes the serial data back to the computer as a way to check if the Arduino isn't interpreting wrong values
   }
   Serial.flush();
+
+  //  Reset all Commands status just to make sure everything is working as intended
+  serial_rx_buffer_controller[0] = 0x01; //  Preamble
+  serial_rx_buffer_controller[1] = 0x00; //  SELECT, L3, R3, START, DUP, DRIGHT, DDOWN, DLEFT
+  serial_rx_buffer_controller[2] = 0x00; //  L2, R2, L1, R1, Triangle/Delta, Circle/O, Cross/X, Square
+  serial_rx_buffer_controller[3] = 0x7F; //  RX
+  serial_rx_buffer_controller[4] = 0x7F; //  RY
+  serial_rx_buffer_controller[5] = 0x7F; //  LX
+  serial_rx_buffer_controller[6] = 0x7F; //  LY
+  serial_rx_buffer_controller[7] = 0x00; //  Analog button (Used to change between Digital and Analog modes in older games), Buffer Array Element 7  //  All other bits in this Buffer Array Element are unused
+  serial_rx_buffer_controller[8] = 0x00; //  Unused
+  serial_rx_buffer_controller[9] = 0x00; //  Delay Byte 2
+  serial_rx_buffer_controller[10] = 0x00; // Delay Byte 1
+  serial_rx_buffer_controller[11] = 0x01; // Postamble
+
+  for (serial_rx_buffer_counter = 0; serial_rx_buffer_counter < sizeof(serial_rx_buffer); serial_rx_buffer_counter++) {
+    Serial.write(serial_rx_buffer_controller[serial_rx_buffer_counter]); //  This line writes the serial data back to the computer as a way to check if the Arduino isn't interpreting wrong values
+    serial_rx_buffer_inverted_controller[serial_rx_buffer_counter] = (255 - serial_rx_buffer_controller[serial_rx_buffer_counter]); //  Invert 0 to 255 and vice versa to make it easier to determine which commands to enable or not, and their values
+  }
+
+  //  First 8 buttons, Buffer Array Element 1
+  //  SELECT, L3, R3, START, DUP, DRIGHT, DDOWN, DLEFT
+  digitalWrite(commandArray[0], (serial_rx_buffer_inverted_controller[1] & B00000001));
+  digitalWrite(commandArray[1], (serial_rx_buffer_inverted_controller[1] & B00000010));
+  digitalWrite(commandArray[2], (serial_rx_buffer_inverted_controller[1] & B00000100));
+  digitalWrite(commandArray[3], (serial_rx_buffer_inverted_controller[1] & B00001000));
+  digitalWrite(commandArray[4], (serial_rx_buffer_inverted_controller[1] & B00010000));
+  digitalWrite(commandArray[5], (serial_rx_buffer_inverted_controller[1] & B00100000));
+  digitalWrite(commandArray[6], (serial_rx_buffer_inverted_controller[1] & B01000000));
+  digitalWrite(commandArray[7], (serial_rx_buffer_inverted_controller[1] & B10000000));
+
+  //  Second 8 buttons, Buffer Array Element 2
+  //  L2, R2, L1, R1, Triangle/Delta, Circle/O, Cross/X, Square
+  digitalWrite(commandArray[8], (serial_rx_buffer_inverted_controller[2] & B00000001));
+  digitalWrite(commandArray[9], (serial_rx_buffer_inverted_controller[2] & B00000010));
+  digitalWrite(commandArray[10], (serial_rx_buffer_inverted_controller[2] & B00000100));
+  digitalWrite(commandArray[11], (serial_rx_buffer_inverted_controller[2] & B00001000));
+  digitalWrite(commandArray[12], (serial_rx_buffer_inverted_controller[2] & B00010000));
+  digitalWrite(commandArray[13], (serial_rx_buffer_inverted_controller[2] & B00100000));
+  digitalWrite(commandArray[14], (serial_rx_buffer_inverted_controller[2] & B01000000));
+  digitalWrite(commandArray[15], (serial_rx_buffer_inverted_controller[2] & B10000000));
+
+  //  4 Axis, Buffer Array Elements 3, 4, 5, 6
+  //  RX, RY, LX, LY
+  analogWrite(commandArray[16], serial_rx_buffer_inverted_controller[3]);
+  analogWrite(commandArray[17], serial_rx_buffer_inverted_controller[4]);
+  analogWrite(commandArray[18], serial_rx_buffer_inverted_controller[5]);
+  analogWrite(commandArray[19], serial_rx_buffer_inverted_controller[6]);
+
+  //  Analog button (Used to change between Digital and Analog modes in older games), Buffer Array Element 7
+  //  All other bits in this Buffer Array Element are unused
+  digitalWrite(commandArray[20], (serial_rx_buffer_inverted_controller[7] & B00000001));
+
+  //  Buffer Array Element 8 is unused in this code, but is existing in case changes are needed
+  Serial.flush();
+
   //Serial.println("RECONNECTED!");
   //Serial.println(disconnectDone);
 }

 void arduinoReset() {
   resetCalled = currentMillis;
+
+  //  Before resetting, we need to reset all Command status, and tell the computer they were reset
+  serial_rx_buffer_controller[0] = 0x01; //  Preamble
+  serial_rx_buffer_controller[1] = 0x00; //  SELECT, L3, R3, START, DUP, DRIGHT, DDOWN, DLEFT
+  serial_rx_buffer_controller[2] = 0x00; //  L2, R2, L1, R1, Triangle/Delta, Circle/O, Cross/X, Square
+  serial_rx_buffer_controller[3] = 0x7F; //  RX
+  serial_rx_buffer_controller[4] = 0x7F; //  RY
+  serial_rx_buffer_controller[5] = 0x7F; //  LX
+  serial_rx_buffer_controller[6] = 0x7F; //  LY
+  serial_rx_buffer_controller[7] = 0x00; //  Analog button (Used to change between Digital and Analog modes in older games), Buffer Array Element 7  //  All other bits in this Buffer Array Element are unused
+  serial_rx_buffer_controller[8] = 0x00; //  Unused
+  serial_rx_buffer_controller[9] = 0x00; //  Delay Byte 2
+  serial_rx_buffer_controller[10] = 0x00; // Delay Byte 1
+  serial_rx_buffer_controller[11] = 0x01; // Postamble
+
+  for (serial_rx_buffer_counter = 0; serial_rx_buffer_counter < sizeof(serial_rx_buffer); serial_rx_buffer_counter++) {
+    Serial.write(serial_rx_buffer_controller[serial_rx_buffer_counter]); //  This line writes the serial data back to the computer as a way to check if the Arduino isn't interpreting wrong values
+    serial_rx_buffer_inverted_controller[serial_rx_buffer_counter] = (255 - serial_rx_buffer_controller[serial_rx_buffer_counter]); //  Invert 0 to 255 and vice versa to make it easier to determine which commands to enable or not, and their values
+  }
+
+  //  First 8 buttons, Buffer Array Element 1
+  //  SELECT, L3, R3, START, DUP, DRIGHT, DDOWN, DLEFT
+  digitalWrite(commandArray[0], (serial_rx_buffer_inverted_controller[1] & B00000001));
+  digitalWrite(commandArray[1], (serial_rx_buffer_inverted_controller[1] & B00000010));
+  digitalWrite(commandArray[2], (serial_rx_buffer_inverted_controller[1] & B00000100));
+  digitalWrite(commandArray[3], (serial_rx_buffer_inverted_controller[1] & B00001000));
+  digitalWrite(commandArray[4], (serial_rx_buffer_inverted_controller[1] & B00010000));
+  digitalWrite(commandArray[5], (serial_rx_buffer_inverted_controller[1] & B00100000));
+  digitalWrite(commandArray[6], (serial_rx_buffer_inverted_controller[1] & B01000000));
+  digitalWrite(commandArray[7], (serial_rx_buffer_inverted_controller[1] & B10000000));
+
+  //  Second 8 buttons, Buffer Array Element 2
+  //  L2, R2, L1, R1, Triangle/Delta, Circle/O, Cross/X, Square
+  digitalWrite(commandArray[8], (serial_rx_buffer_inverted_controller[2] & B00000001));
+  digitalWrite(commandArray[9], (serial_rx_buffer_inverted_controller[2] & B00000010));
+  digitalWrite(commandArray[10], (serial_rx_buffer_inverted_controller[2] & B00000100));
+  digitalWrite(commandArray[11], (serial_rx_buffer_inverted_controller[2] & B00001000));
+  digitalWrite(commandArray[12], (serial_rx_buffer_inverted_controller[2] & B00010000));
+  digitalWrite(commandArray[13], (serial_rx_buffer_inverted_controller[2] & B00100000));
+  digitalWrite(commandArray[14], (serial_rx_buffer_inverted_controller[2] & B01000000));
+  digitalWrite(commandArray[15], (serial_rx_buffer_inverted_controller[2] & B10000000));
+
+  //  4 Axis, Buffer Array Elements 3, 4, 5, 6
+  //  RX, RY, LX, LY
+  analogWrite(commandArray[16], serial_rx_buffer_inverted_controller[3]);
+  analogWrite(commandArray[17], serial_rx_buffer_inverted_controller[4]);
+  analogWrite(commandArray[18], serial_rx_buffer_inverted_controller[5]);
+  analogWrite(commandArray[19], serial_rx_buffer_inverted_controller[6]);
+
+  //  Analog button (Used to change between Digital and Analog modes in older games), Buffer Array Element 7
+  //  All other bits in this Buffer Array Element are unused
+  digitalWrite(commandArray[20], (serial_rx_buffer_inverted_controller[7] & B00000001));
+
+  //  Buffer Array Element 8 is unused in this code, but is existing in case changes are needed
+  Serial.flush();
+
+  //  Tell the computer the Arduino is about to be Reset
   serial_rx_buffer_reset[8] = (byte)((resetCalled & 0xFF));
   serial_rx_buffer_reset[7] = (byte)((resetCalled >> 8) & 0xFF);
   serial_rx_buffer_reset[6] = (byte)((resetCalled >> 16) & 0xFF);
@@ -456,6 +627,7 @@
     Serial.write(serial_rx_buffer_reset[serial_rx_buffer_counter]); //  This line writes the serial data back to the computer as a way to check if the Arduino isn't interpreting wrong values
   }
   Serial.flush();
+  //  Tell the computer the connection is about to be closed
   disconnectCalled = currentMillis;
   serial_rx_buffer_disconnect[8] = (byte)((disconnectCalled & 0xFF));
   serial_rx_buffer_disconnect[7] = (byte)((disconnectCalled >> 8) & 0xFF);
@@ -472,7 +644,77 @@
   Serial.end();
   isConnected = false;
   disconnectDone = currentMillis;
-  delay(2500); // Wait 2.5 seconds before resetting
+  delay(2500); // Wait 2.5 seconds before resetting
+  Serial.begin(baudRate);
+
+  //  Tell the computer the connection has began succesfully
+  serial_rx_buffer_disconnect[0] = 0x0B;
+  serial_rx_buffer_disconnect[11] = 0x0B;
+  serial_rx_buffer_disconnect[8] = (byte)((disconnectDone & 0xFF));
+  serial_rx_buffer_disconnect[7] = (byte)((disconnectDone >> 8) & 0xFF);
+  serial_rx_buffer_disconnect[6] = (byte)((disconnectDone >> 16) & 0xFF);
+  serial_rx_buffer_disconnect[5] = (byte)((disconnectDone >> 24) & 0xFF);
+  for (serial_rx_buffer_counter = 0; serial_rx_buffer_counter < sizeof(serial_rx_buffer_disconnect); serial_rx_buffer_counter++) {
+    Serial.write(serial_rx_buffer_disconnect[serial_rx_buffer_counter]); //  This line writes the serial data back to the computer as a way to check if the Arduino isn't interpreting wrong values
+  }
+  Serial.flush();
+
+  //  Reset all commands again just to make sure
+  serial_rx_buffer_controller[0] = 0x01; //  Preamble
+  serial_rx_buffer_controller[1] = 0x00; //  SELECT, L3, R3, START, DUP, DRIGHT, DDOWN, DLEFT
+  serial_rx_buffer_controller[2] = 0x00; //  L2, R2, L1, R1, Triangle/Delta, Circle/O, Cross/X, Square
+  serial_rx_buffer_controller[3] = 0x7F; //  RX
+  serial_rx_buffer_controller[4] = 0x7F; //  RY
+  serial_rx_buffer_controller[5] = 0x7F; //  LX
+  serial_rx_buffer_controller[6] = 0x7F; //  LY
+  serial_rx_buffer_controller[7] = 0x00; //  Analog button (Used to change between Digital and Analog modes in older games), Buffer Array Element 7  //  All other bits in this Buffer Array Element are unused
+  serial_rx_buffer_controller[8] = 0x00; //  Unused
+  serial_rx_buffer_controller[9] = 0x00; //  Delay Byte 2
+  serial_rx_buffer_controller[10] = 0x00; // Delay Byte 1
+  serial_rx_buffer_controller[11] = 0x01; // Postamble
+
+  for (serial_rx_buffer_counter = 0; serial_rx_buffer_counter < sizeof(serial_rx_buffer); serial_rx_buffer_counter++) {
+    Serial.write(serial_rx_buffer_controller[serial_rx_buffer_counter]); //  This line writes the serial data back to the computer as a way to check if the Arduino isn't interpreting wrong values
+    serial_rx_buffer_inverted_controller[serial_rx_buffer_counter] = (255 - serial_rx_buffer_controller[serial_rx_buffer_counter]); //  Invert 0 to 255 and vice versa to make it easier to determine which commands to enable or not, and their values
+  }
+
+  //  First 8 buttons, Buffer Array Element 1
+  //  SELECT, L3, R3, START, DUP, DRIGHT, DDOWN, DLEFT
+  digitalWrite(commandArray[0], (serial_rx_buffer_inverted_controller[1] & B00000001));
+  digitalWrite(commandArray[1], (serial_rx_buffer_inverted_controller[1] & B00000010));
+  digitalWrite(commandArray[2], (serial_rx_buffer_inverted_controller[1] & B00000100));
+  digitalWrite(commandArray[3], (serial_rx_buffer_inverted_controller[1] & B00001000));
+  digitalWrite(commandArray[4], (serial_rx_buffer_inverted_controller[1] & B00010000));
+  digitalWrite(commandArray[5], (serial_rx_buffer_inverted_controller[1] & B00100000));
+  digitalWrite(commandArray[6], (serial_rx_buffer_inverted_controller[1] & B01000000));
+  digitalWrite(commandArray[7], (serial_rx_buffer_inverted_controller[1] & B10000000));
+
+  //  Second 8 buttons, Buffer Array Element 2
+  //  L2, R2, L1, R1, Triangle/Delta, Circle/O, Cross/X, Square
+  digitalWrite(commandArray[8], (serial_rx_buffer_inverted_controller[2] & B00000001));
+  digitalWrite(commandArray[9], (serial_rx_buffer_inverted_controller[2] & B00000010));
+  digitalWrite(commandArray[10], (serial_rx_buffer_inverted_controller[2] & B00000100));
+  digitalWrite(commandArray[11], (serial_rx_buffer_inverted_controller[2] & B00001000));
+  digitalWrite(commandArray[12], (serial_rx_buffer_inverted_controller[2] & B00010000));
+  digitalWrite(commandArray[13], (serial_rx_buffer_inverted_controller[2] & B00100000));
+  digitalWrite(commandArray[14], (serial_rx_buffer_inverted_controller[2] & B01000000));
+  digitalWrite(commandArray[15], (serial_rx_buffer_inverted_controller[2] & B10000000));
+
+  //  4 Axis, Buffer Array Elements 3, 4, 5, 6
+  //  RX, RY, LX, LY
+  analogWrite(commandArray[16], serial_rx_buffer_inverted_controller[3]);
+  analogWrite(commandArray[17], serial_rx_buffer_inverted_controller[4]);
+  analogWrite(commandArray[18], serial_rx_buffer_inverted_controller[5]);
+  analogWrite(commandArray[19], serial_rx_buffer_inverted_controller[6]);
+
+  //  Analog button (Used to change between Digital and Analog modes in older games), Buffer Array Element 7
+  //  All other bits in this Buffer Array Element are unused
+  digitalWrite(commandArray[20], (serial_rx_buffer_inverted_controller[7] & B00000001));
+
+  //  Buffer Array Element 8 is unused in this code, but is existing in case changes are needed
+  Serial.flush();
+
+  //  Tell the computer the Arduino has been reset succesfully
   resetDone = currentMillis;
   serial_rx_buffer_reset[0] = 0xA1;
   serial_rx_buffer_reset[11] = 0xA1;
@@ -793,7 +1035,7 @@
       Serial.print("CURRENT PONG CALCULATED = ");
       Serial.println(calcPongTimestamp);
       Serial.flush();
-      Serial.print("CURRENT PING CALCULATED = ");
+      Serial.print("CURRENT PING CALCULATED = ");
       Serial.println(calcPingTimestamp);
       Serial.flush();
     */
@@ -808,6 +1050,63 @@
   calcPingTimestampIn = (currentMillis - previousPingDelay);
   if ((calcPongTimestampIn - calcPingTimestampIn >= 10000) && (calcPongTimestampIn - calcPingTimestampIn <= currentMillis)) {
     disconnectCalled = currentMillis;
+
+    //  Before disconnecting, we need to reset all Command status, and tell the computer they were reset
+    serial_rx_buffer_controller[0] = 0x01; //  Preamble
+    serial_rx_buffer_controller[1] = 0x00; //  SELECT, L3, R3, START, DUP, DRIGHT, DDOWN, DLEFT
+    serial_rx_buffer_controller[2] = 0x00; //  L2, R2, L1, R1, Triangle/Delta, Circle/O, Cross/X, Square
+    serial_rx_buffer_controller[3] = 0x7F; //  RX
+    serial_rx_buffer_controller[4] = 0x7F; //  RY
+    serial_rx_buffer_controller[5] = 0x7F; //  LX
+    serial_rx_buffer_controller[6] = 0x7F; //  LY
+    serial_rx_buffer_controller[7] = 0x00; //  Analog button (Used to change between Digital and Analog modes in older games), Buffer Array Element 7  //  All other bits in this Buffer Array Element are unused
+    serial_rx_buffer_controller[8] = 0x00; //  Unused
+    serial_rx_buffer_controller[9] = 0x00; //  Delay Byte 2
+    serial_rx_buffer_controller[10] = 0x00; // Delay Byte 1
+    serial_rx_buffer_controller[11] = 0x01; // Postamble
+
+    for (serial_rx_buffer_counter = 0; serial_rx_buffer_counter < sizeof(serial_rx_buffer); serial_rx_buffer_counter++) {
+      Serial.write(serial_rx_buffer_controller[serial_rx_buffer_counter]); //  This line writes the serial data back to the computer as a way to check if the Arduino isn't interpreting wrong values
+      serial_rx_buffer_inverted_controller[serial_rx_buffer_counter] = (255 - serial_rx_buffer_controller[serial_rx_buffer_counter]); //  Invert 0 to 255 and vice versa to make it easier to determine which commands to enable or not, and their values
+    }
+
+    //  First 8 buttons, Buffer Array Element 1
+    //  SELECT, L3, R3, START, DUP, DRIGHT, DDOWN, DLEFT
+    digitalWrite(commandArray[0], (serial_rx_buffer_inverted_controller[1] & B00000001));
+    digitalWrite(commandArray[1], (serial_rx_buffer_inverted_controller[1] & B00000010));
+    digitalWrite(commandArray[2], (serial_rx_buffer_inverted_controller[1] & B00000100));
+    digitalWrite(commandArray[3], (serial_rx_buffer_inverted_controller[1] & B00001000));
+    digitalWrite(commandArray[4], (serial_rx_buffer_inverted_controller[1] & B00010000));
+    digitalWrite(commandArray[5], (serial_rx_buffer_inverted_controller[1] & B00100000));
+    digitalWrite(commandArray[6], (serial_rx_buffer_inverted_controller[1] & B01000000));
+    digitalWrite(commandArray[7], (serial_rx_buffer_inverted_controller[1] & B10000000));
+
+    //  Second 8 buttons, Buffer Array Element 2
+    //  L2, R2, L1, R1, Triangle/Delta, Circle/O, Cross/X, Square
+    digitalWrite(commandArray[8], (serial_rx_buffer_inverted_controller[2] & B00000001));
+    digitalWrite(commandArray[9], (serial_rx_buffer_inverted_controller[2] & B00000010));
+    digitalWrite(commandArray[10], (serial_rx_buffer_inverted_controller[2] & B00000100));
+    digitalWrite(commandArray[11], (serial_rx_buffer_inverted_controller[2] & B00001000));
+    digitalWrite(commandArray[12], (serial_rx_buffer_inverted_controller[2] & B00010000));
+    digitalWrite(commandArray[13], (serial_rx_buffer_inverted_controller[2] & B00100000));
+    digitalWrite(commandArray[14], (serial_rx_buffer_inverted_controller[2] & B01000000));
+    digitalWrite(commandArray[15], (serial_rx_buffer_inverted_controller[2] & B10000000));
+
+    //  4 Axis, Buffer Array Elements 3, 4, 5, 6
+    //  RX, RY, LX, LY
+    analogWrite(commandArray[16], serial_rx_buffer_inverted_controller[3]);
+    analogWrite(commandArray[17], serial_rx_buffer_inverted_controller[4]);
+    analogWrite(commandArray[18], serial_rx_buffer_inverted_controller[5]);
+    analogWrite(commandArray[19], serial_rx_buffer_inverted_controller[6]);
+
+    //  Analog button (Used to change between Digital and Analog modes in older games), Buffer Array Element 7
+    //  All other bits in this Buffer Array Element are unused
+    digitalWrite(commandArray[20], (serial_rx_buffer_inverted_controller[7] & B00000001));
+
+    //  Buffer Array Element 8 is unused in this code, but is existing in case changes are needed
+    Serial.flush();
+
+    //  Tell the computer the connection is about to be closed
     serial_rx_buffer_disconnect[8] = (byte)((disconnectCalled & 0xFF));
     serial_rx_buffer_disconnect[7] = (byte)((disconnectCalled >> 8) & 0xFF);
     serial_rx_buffer_disconnect[6] = (byte)((disconnectCalled >> 16) & 0xFF);
@@ -817,11 +1116,11 @@
     //Serial.print("DISCONNECTING PING = ");
     //Serial.println(calcPongTimestampIn);
     serial_rx_buffer_disconnect[0] = 0x09;
-    serial_rx_buffer_disconnect[11] = 0x09;
+    serial_rx_buffer_disconnect[11] = 0x09;
     for (serial_rx_buffer_counter = 0; serial_rx_buffer_counter < sizeof(serial_rx_buffer_disconnect); serial_rx_buffer_counter++) {
       Serial.write(serial_rx_buffer_disconnect[serial_rx_buffer_counter]); //  This line writes the serial data back to the computer as a way to check if the Arduino isn't interpreting wrong values
     }
-    Serial.flush();
+    Serial.flush();
     //calcPongTimestamp = 0;
     previousPongDelay = currentMillis;
     //Serial.println("Closing connection");
@@ -832,18 +1131,75 @@
     //Serial.println("Sending shit after connection has closed");
     Serial.begin(baudRate);
     //Serial.println("Connection started");
+    //  Tell the computer the connection has began succesfully
     serial_rx_buffer_disconnect[0] = 0x0B;
     serial_rx_buffer_disconnect[11] = 0x0B;
-    isConnected = true;
-    disconnectDone = currentMillis;
     serial_rx_buffer_disconnect[8] = (byte)((disconnectDone & 0xFF));
     serial_rx_buffer_disconnect[7] = (byte)((disconnectDone >> 8) & 0xFF);
-    serial_rx_buffer_disconnect[6] = (byte)((disconnectDone >> 16) & 0xFF);
+    serial_rx_buffer_disconnect[6] = (byte)((disconnectDone >> 16) & 0xFF);
     serial_rx_buffer_disconnect[5] = (byte)((disconnectDone >> 24) & 0xFF);
     for (serial_rx_buffer_counter = 0; serial_rx_buffer_counter < sizeof(serial_rx_buffer_disconnect); serial_rx_buffer_counter++) {
       Serial.write(serial_rx_buffer_disconnect[serial_rx_buffer_counter]); //  This line writes the serial data back to the computer as a way to check if the Arduino isn't interpreting wrong values
     }
     Serial.flush();
+
+    //  Reset all Commands status just to make sure everything is working as intended
+    serial_rx_buffer_controller[0] = 0x01; //  Preamble
+    serial_rx_buffer_controller[1] = 0x00; //  SELECT, L3, R3, START, DUP, DRIGHT, DDOWN, DLEFT
+    serial_rx_buffer_controller[2] = 0x00; //  L2, R2, L1, R1, Triangle/Delta, Circle/O, Cross/X, Square
+    serial_rx_buffer_controller[3] = 0x7F; //  RX
+    serial_rx_buffer_controller[4] = 0x7F; //  RY
+    serial_rx_buffer_controller[5] = 0x7F; //  LX
+    serial_rx_buffer_controller[6] = 0x7F; //  LY
+    serial_rx_buffer_controller[7] = 0x00; //  Analog button (Used to change between Digital and Analog modes in older games), Buffer Array Element 7  //  All other bits in this Buffer Array Element are unused
+    serial_rx_buffer_controller[8] = 0x00; //  Unused
+    serial_rx_buffer_controller[9] = 0x00; //  Delay Byte 2
+    serial_rx_buffer_controller[10] = 0x00; // Delay Byte 1
+    serial_rx_buffer_controller[11] = 0x01; // Postamble
+
+    for (serial_rx_buffer_counter = 0; serial_rx_buffer_counter < sizeof(serial_rx_buffer); serial_rx_buffer_counter++) {
+      Serial.write(serial_rx_buffer_controller[serial_rx_buffer_counter]); //  This line writes the serial data back to the computer as a way to check if the Arduino isn't interpreting wrong values
+      serial_rx_buffer_inverted_controller[serial_rx_buffer_counter] = (255 - serial_rx_buffer_controller[serial_rx_buffer_counter]); //  Invert 0 to 255 and vice versa to make it easier to determine which commands to enable or not, and their values
+    }
+
+    //  First 8 buttons, Buffer Array Element 1
+    //  SELECT, L3, R3, START, DUP, DRIGHT, DDOWN, DLEFT
+    digitalWrite(commandArray[0], (serial_rx_buffer_inverted_controller[1] & B00000001));
+    digitalWrite(commandArray[1], (serial_rx_buffer_inverted_controller[1] & B00000010));
+    digitalWrite(commandArray[2], (serial_rx_buffer_inverted_controller[1] & B00000100));
+    digitalWrite(commandArray[3], (serial_rx_buffer_inverted_controller[1] & B00001000));
+    digitalWrite(commandArray[4], (serial_rx_buffer_inverted_controller[1] & B00010000));
+    digitalWrite(commandArray[5], (serial_rx_buffer_inverted_controller[1] & B00100000));
+    digitalWrite(commandArray[6], (serial_rx_buffer_inverted_controller[1] & B01000000));
+    digitalWrite(commandArray[7], (serial_rx_buffer_inverted_controller[1] & B10000000));
+
+    //  Second 8 buttons, Buffer Array Element 2
+    //  L2, R2, L1, R1, Triangle/Delta, Circle/O, Cross/X, Square
+    digitalWrite(commandArray[8], (serial_rx_buffer_inverted_controller[2] & B00000001));
+    digitalWrite(commandArray[9], (serial_rx_buffer_inverted_controller[2] & B00000010));
+    digitalWrite(commandArray[10], (serial_rx_buffer_inverted_controller[2] & B00000100));
+    digitalWrite(commandArray[11], (serial_rx_buffer_inverted_controller[2] & B00001000));
+    digitalWrite(commandArray[12], (serial_rx_buffer_inverted_controller[2] & B00010000));
+    digitalWrite(commandArray[13], (serial_rx_buffer_inverted_controller[2] & B00100000));
+    digitalWrite(commandArray[14], (serial_rx_buffer_inverted_controller[2] & B01000000));
+    digitalWrite(commandArray[15], (serial_rx_buffer_inverted_controller[2] & B10000000));
+
+    //  4 Axis, Buffer Array Elements 3, 4, 5, 6
+    //  RX, RY, LX, LY
+    analogWrite(commandArray[16], serial_rx_buffer_inverted_controller[3]);
+    analogWrite(commandArray[17], serial_rx_buffer_inverted_controller[4]);
+    analogWrite(commandArray[18], serial_rx_buffer_inverted_controller[5]);
+    analogWrite(commandArray[19], serial_rx_buffer_inverted_controller[6]);
+
+    //  Analog button (Used to change between Digital and Analog modes in older games), Buffer Array Element 7
+    //  All other bits in this Buffer Array Element are unused
+    digitalWrite(commandArray[20], (serial_rx_buffer_inverted_controller[7] & B00000001));
+
+    //  Buffer Array Element 8 is unused in this code, but is existing in case changes are needed
+    Serial.flush();
+
+    isConnected = true;
+    disconnectDone = currentMillis;
     //Serial.println("Sending shit after connection has began");
     //Serial.println("RECONNECTED!");
     //Serial.println(calcPongTimestampIn);


Telnet Improvements

Telnet Improvements

--- MicroView/WiFiCartTelnetTest/WiFiCartTelnetTest.ino
+++ MicroView/WiFiCartTelnetTest/WiFiCartTelnetTest.ino
@@ -37,6 +37,8 @@
 // Telnet Stuff
 #define IAC 255

+String lastHost = "";
+
 // ----------------------------------------------------------

 char temp[100];
@@ -74,30 +76,21 @@
    C64Serial.print("host: ");
    C64Serial.setTimeout(1000);

-   String readString = "";
-   bool changed=false;
-   long c64_chars=0;
-
-   while (true)
-   {
-     while (C64Serial.available() > 0)
-     {
-       c64_chars++;
-       char c = C64Serial.read();
-       C64Serial.print(c); // Echo
-
-       if ((int)c == 13)
-       {
-         Telnet(readString);
-         return;
-       }
-       else
-       {
-         readString += c;
-       }
-     }
-   }
-}
+   String readString = GetInput();
+   readString.trim();
+
+   if (readString.length() > 0)
+   {
+     lastHost = readString;
+     Telnet(readString);
+   }
+   else
+   {
+      Telnet(lastHost);
+   }
+}
+
+// ----------------------------------------------------------

 void display(String message)
 {
@@ -107,15 +100,46 @@
    uView.display();
 }

+
 void display2(String message)
 {
    display(message);
    C64Serial.println(message);
 }

+// ----------------------------------------------------------
+
+String GetInput()
+{
+  char in_char[100];
+  int max_length=sizeof(in_char);
+
+  int i=0; // Input buffer pointer
+  char key;
+
+  while(true)
+  {
+      key=ReadByte(C64Serial); // Read in one character
+      in_char[i]=key;
+      C64Serial.write(key); // Echo key press back to the user.
+
+      if ((key=='\b')&&(i>0)) i-=2; // Handles back space.
+
+      if (((int)key==13)||(i==max_length-1))
+      { // The \n represents enter key.
+        in_char[i]=0; // Terminate the string with 0.
+        return String(in_char);
+      }
+      i++;
+      if (i<0) i=0;
+  }
+}
+
+// ----------------------------------------------------------
+
 void Telnet(String host)
 {
-   sprintf(temp, "\n\nOpening Telnet connection to %s", host.c_str() );
+   sprintf(temp, "Connecting to %s", host.c_str() );
    display2(temp);

    wifly.setIpProtocol(WIFLY_PROTOCOL_TCP);
@@ -124,7 +148,8 @@

    if (ok)
    {
-      display2("Connected");
+      sprintf(temp, "Connected to %s", host.c_str() );
+      display2(temp);
    }
    else
    {
@@ -132,10 +157,7 @@
      return;
    }

-   TerminalMode();
-
-
-
+   TerminalMode();
 }

 void TerminalMode()
@@ -155,6 +177,12 @@
      {
         wifly.write( C64Serial.read() );
      }
+
+     // Alternate check
+     if (!wifly.isConnected())
+     {
+        break;
+     }
    }

     wifly.close();
@@ -168,7 +196,7 @@
   int inpint, verbint, optint;                         //    telnet parameters as integers

   // Wait for first character
-  inpint = PeekByte();
+  inpint = PeekByte(wifly);
   if (inpint != IAC)
   {
     C64Serial.println("Raw TCP Connection Detected");
@@ -182,7 +210,7 @@

   while (true)
   {
-    inpint = PeekByte();       //      peek at next character
+    inpint = PeekByte(wifly);       //      peek at next character

     if (inpint != IAC)
     {
@@ -192,12 +220,8 @@
       return;   // Let Terminal mode handle character
     }

-    inpint = ReadByte();    // Eat IAC character
-    verbint = ReadByte();   // receive negotiation verb character
-
-    C64Serial.print("Received verbint=");
-    C64Serial.println(verbint);
-
+    inpint = ReadByte(wifly);    // Eat IAC character
+    verbint = ReadByte(wifly);   // receive negotiation verb character
     if (verbint == - 1) continue;                //          if negotiation verb character is nothing break the routine  (should never happen)

     switch (verbint) {                             //          evaluate negotiation verb character
@@ -208,14 +232,9 @@
         case 252:                                    //          if negotiation verb character is 252 (wont) or
         case 253:                                    //          if negotiation verb character is 253 (do) or
         case 254:                                    //          if negotiation verb character is 254 (dont)
-          optint = ReadByte();                   //            receive negotiation option character
-
-           C64Serial.print("Received optint=");
-           C64Serial.println(optint);
-
-          if (optint == -1) continue;                   //            if negotiation option character is nothing break the routine
-
-
+          optint = ReadByte(wifly);                  //            receive negotiation option character
+          if (optint == -1) continue;                   //            if negotiation option character is nothing break the routine  (should never happen)
+
           switch (optint) {

             case 3:                                   // if negotiation option character is 3 (suppress-go-ahead)
@@ -255,14 +274,15 @@
   wifly.write(1);                             // echo
 }

-int ReadByte()
-{
-    while (wifly.available() == 0) {}
-    return wifly.read();
-}
-
-int PeekByte()
-{
-    while (wifly.available() == 0) {}
-    return wifly.peek();
-}
+int ReadByte(Stream& in)
+{
+    while (in.available() == 0) {}
+    return in.read();
+}
+
+int PeekByte(Stream& in)
+{
+    while (in.available() == 0) {}
+    return in.peek();
+}
+


setTimeout

setTimeout

--- example/echo/echo.ino
+++ example/echo/echo.ino
@@ -38,10 +38,16 @@
   // client.BorgTopicSend("myTopic", String(54321));
 }

+void borgTimeoutCb()
+{
+  debugPort->println(F("Hello Timeout!"));
+}
+
 void setup() {
   attachInterrupt(0, buttonISR, RISING);
   client.BorgDevConnect(borgDevCb);
   client.setInterval(borgIntervalCb, 10000);
+  client.setTimeout(borgTimeoutCb, 5000, 3);
 }

 void loop() {


More work on file naming and watchdog interupt. Added a vimrc

--- system_monitor/system_monitor.ino
+++ system_monitor/system_monitor.ino
@@ -15,8 +15,11 @@
 #include <Wire.h>
 #include "RTClib.h"
 #include <avr/sleep.h> //for sleeping
+#include <avr/power.h> //for sleeping deep
 #include <avr/wdt.h> //for waking up

+#define FALSE 0
+#define TRUE 1
 #define AREF_VOLT 4.096 //Using an external voltage reference (LM4040)
 #define TEST 1 //Used during testing to enable/disable certain functionality
 #define NAME_LENGTH 25 // Length of the filenames
@@ -25,9 +28,13 @@
 #define RED_LED_PIN 3
 #define GREEN_LED_PIN 4

+// Flag is set by the watch dog timer (WDT)
+char WDT_FLAG = FALSE;
+
+
 // Global variable containing the current filename
 //char *filename = (char*)malloc(NAME_LENGTH);
-char filename[25];
+char filename[33];

 const char NUM_SOURCES = 4; //number of voltage/current sources
 // System Order: Batt, Solar, Hydro, Load
@@ -57,36 +64,30 @@

 ISR(WDT_vect){
     // After interupt, the script goes here
-  wdt_disable();  // disable watchdog
+  //wdt_disable();  // disable watchdog
+    WDT_FLAG = TRUE;
 }

 void sleep(){
-  // This is how we sleep
-  MCUSR = 0;                          // reset various flags
-  WDTCSR |= 0b00011000;               // see docs, set WDCE, WDE
-  WDTCSR =  0b01000000 | 0b100001;    // set WDIE, and appropriate delay
-// sleep bit patterns:
-//  1 second:  0b000110
-//  2 seconds: 0b000111
-//  4 seconds: 0b100000
-//  8 seconds: 0b100001
-  wdt_reset();
-  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
-  sleep_mode();            // now goes to Sleep and waits for the interrupt
+    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+    sleep_enable();
+
+    /* Now enter sleep mode. */
+    sleep_mode();
+
+    /* The program will continue from here after the WDT timeout*/
+    sleep_disable(); /* First thing to do is disable sleep. */
+
+    /* Re-enable the peripherals. */
+    power_all_enable();
   }

 float* readVoltage(){
-    static float voltages[4] = {0, 1, 0, 0};
-    #if TEST
-        serialOut("readVoltage");
-        for(int i=0; i<NUM_SOURCES; i++){
-            voltages[i] = 13.8+i;
-        }
-        //return voltages;
-    #endif
+    static float voltages[4] = {0, 0, 0, 0};
+    serialOut("readVoltage");

     for(int i=0; i<NUM_SOURCES; i++){
-        voltages[i] =  analogRead(VOLT_PIN[i]) * VOLT_MULTI[i];
+        voltages[i] =  analogRead(VOLT_PIN[i]) * (AREF_VOLT/1024) * VOLT_MULTI[i];
     }
     return voltages;
 }//readVoltage
@@ -102,7 +103,7 @@
     #endif

     for(int i=0; i<NUM_SOURCES; i++){
-        amps[i] =  analogRead(AMP_PIN[i]) * AMP_MULTI[i];
+        amps[i] =  analogRead(AMP_PIN[i]) * (AREF_VOLT/1024) * AMP_MULTI[i];
     }
     return amps;
 }//readAmp
@@ -125,12 +126,15 @@

 void readTime(char *time){
     // TO DO
+
     #if TEST
         serialOut("readTime");
     #endif
     //static char *time;
     //char *temp;

+    //unixTime = now.unixtime();
+
     int randNumber = random(100);
     sprintf(time, "%09d", randNumber);
     //time = &temp;
@@ -154,17 +158,45 @@

 void newFile(){

-    char header[] =
+    // File format should be: UNIXTIME_yyyy-mm-ddThhmmss
+    // For example: 1506907892_2017-10-02T193101.csv
+    // which is: 2017/Oct/02 7:39:01pm
+    /*
+    int unix   = now.unixtime();
+    int year   = now.year();
+    int month  = now.month();
+    int day    = now.day();
+    int hour   = now.hour();
+    int minute = now.minute();
+    int second = now.second();
+    */
+    unsigned long unix   = 1506907891;
+    int year   = 2017;
+    int month  = 10;
+    int day    = 2;
+    int hour   = 19;
+    int minute = 31;
+    int second = 4;
+
+    char buff[580];
+    char *header = buff;
+    sprintf(header,
         "#Thanksgiving Cabin Power System\n"
+        "#Time is in UNIX Time which is the number of seconds since 1970-Jan-01\n"
+        "#To convert the date in cell 'A7' to an excel date serial number "
+        "in Vancover time use:\n"
+        "#=(A7/86400)+25569+(-7/24)\n"
+        "or Google it\n"
+        "Created: %04d-%02d-%02d at %02d:%02d:%02d or %010lu in UNIX time"
         "#Timestamp,Battery Voltage,Solar Voltage,Hydro Voltage,Load Voltage,"
         "Battery Amps, Solar Amps,Hydro Amps,Load Amps,Battery Energy State,"
-        "Outside Temp,Cabin Temp,Battery Temp\n";
-
-    char buff[NAME_LENGTH];
-    char *temp = buff;
-    readTime(temp);
-    strcat(temp, ".csv");
-    memcpy(filename, temp, sizeof(char)*NAME_LENGTH);
+        "Outside Temp,Cabin Temp,Battery Temp\n", year, month, day, hour, minute, second, unix);
+
+    sprintf(filename, "%010lu_%04d-%02d-%02dT%02d%02d%02d.csv", unix, year, month, day, hour, minute, second);
+
+    //readTime(temp);
+    //strcat(temp, ".csv");
+    //memcpy(filename, temp, sizeof(char)*NAME_LENGTH);
 #if TEST
     return;
 #endif
@@ -226,11 +258,14 @@

 void test(){

-    char buff[25];
-    char *time = buff;
-
-    float *voltages, *amps, *temps;
+    char buff[25]; //Allocate memory for the 'time'
+    char *time = buff; //Create pointer to the allocated memory
+    float *voltages, *amps, *temps; //create pointers to point at data
+
     voltages = readVoltage();
+    int voltAdd = voltages;
+    Serial.println(voltAdd);
+    delay(5);
     amps = readAmp();
     temps = readTemp();
     readTime(time);
@@ -243,7 +278,7 @@
     newFile();
     serialOut("New filename:");
     serialOut(filename);
-    //delay(100);
+    //delay(2000);
     sleep();
     return;
 }
@@ -255,6 +290,22 @@

     pinMode(RED_LED_PIN, OUTPUT);
     pinMode(GREEN_LED_PIN, OUTPUT);
+
+    //Using an external voltage reference for increased accuracy
+    analogReference(EXTERNAL);
+    analogRead(0); //To help settle the ADC before taking readings
+
+    // WDT setup
+    cli(); //disable interrupts
+    wdt_reset();
+    // Enter 'Config mode'
+    WDTCSR |= (1<<WDCE) | (1<<WDE);
+
+    // Set interupts, reset on timeout, last 4 do time (1001 is 8sec)
+    WDTCSR = (1<<WDIE) | (0<<WDE) | (1<<WDP3) | (0<<WDP2) | (0<<WDP1) | (1<<WDP0);
+
+    sei(); //enable interupts
+

 #if !(TEST)
     // initialize the SD card
@@ -286,4 +337,8 @@
 void loop() {
     // TO DO
     test();
-}
+
+    if(WDT_FLAG == TRUE){
+        WDT_FLAG = FALSE;
+    }
+}


COH-72: WIP

COH-72: WIP

--- V0p2_Main/V0p2_Main.ino
+++ V0p2_Main/V0p2_Main.ino
@@ -159,7 +159,6 @@
   OTV0P2BASE::serialPrintlnAndFlush();
   }

-// FIXME Temporary fix
 #ifdef ALLOW_CC1_SUPPORT
 static const uint8_t nPrimaryRadioChannels = 2;
 static const OTRadioLink::OTRadioChannelConfig RFMConfigs[nPrimaryRadioChannels] =
@@ -273,7 +272,7 @@
   // Initialise the radio, if configured, ASAP because it can suck a lot of power until properly initialised.
   PrimaryRadio.preinit(NULL);
   // Check that the radio is correctly connected; panic if not...
-  if(!PrimaryRadio.configure(nPrimaryRadioChannels, RFMConfigs) || !PrimaryRadio.begin()) { panic(); }
+  if(!PrimaryRadio.configure(nPrimaryRadioChannels, RFMConfigs) || !PrimaryRadio.begin()) { panic(F("r1")); }
   // Apply filtering, if any, while we're having fun...
   PrimaryRadio.setFilterRXISR(FilterRXISR);
 //  if(neededToWakeSPI) { OTV0P2BASE::powerDownSPI(); }
@@ -288,7 +287,7 @@
 // Initialise the radio, if configured, ASAP because it can suck a lot of power until properly initialised.
   SecondaryRadio.preinit(NULL);
   // Check that the radio is correctly connected; panic if not...
-  if(!SecondaryRadio.configure(1, &SecondaryRadioConfig) || !SecondaryRadio.begin()) { panic(); }
+  if(!SecondaryRadio.configure(1, &SecondaryRadioConfig) || !SecondaryRadio.begin()) { panic(F("r2")); }
   // Apply filtering, if any, while we're having fun...
 //  SecondaryRadio.setFilterRXISR(FilterRXISR); // Assume no RX on secondary radio.
 #endif // ENABLE_RADIO_SECONDARY_MODULE


Remove unnecessary 'return' statement.

Remove unnecessary 'return' statement.

The `terminalError` function never returns so this return statement is
just wasted bytes.

--- printer.ino
+++ printer.ino
@@ -165,7 +165,6 @@
     if (!SD.remove(cacheFilename)) {
       // Failed to clear cache.
       terminalError(3);
-      return;
     }
   }
   File cache = SD.open(cacheFilename, FILE_WRITE);


commands now start with an @

commands now start with an @

--- Firmware/Api.ino
+++ Firmware/Api.ino
@@ -17,11 +17,11 @@
     Serial.println(command);
 }

-void api_init()
+void api_begin()
 {
-    serialCommand.addCommand("start", api_start);
-    serialCommand.addCommand("stop", api_stop);
-    serialCommand.addCommand("v", api_v);
+    serialCommand.addCommand("@start", api_start);
+    serialCommand.addCommand("@stop", api_stop);
+    serialCommand.addCommand("@v", api_v);
     serialCommand.setDefaultHandler(api_unknown);
 }

@@ -32,40 +32,40 @@
 /**
  * Start the engines
  *
- * Usage: "start"
+ * Usage: "@start"
  */
 void api_start()
 {
-    for (int i = 0; i < 4; i++)
+    for (int wheel = 0; wheel < 4; wheel++)
     {
-        robot_initNode(i);
+        robot_initWheel(wheel);
     }
 }

 /**
  * Perform a quick stop
  *
- * Usage: "stop"
+ * Usage: "@stop"
  */
 void api_stop()
 {
-    for (int i = 0; i < 4; i++)
+    for (int wheel = 0; wheel < 4; wheel++)
     {
-        robot_quickStop(i);
+        robot_quickStop(wheel);
     }
 }

 /**
  * Set the desired velocity for each robot wheel.
  *
- * Usage: "v [wheel 1] [wheel 2] [wheel 3] [wheel 4]"
+ * Usage: "@v [wheel 1] [wheel 2] [wheel 3] [wheel 4]"
  * Range: -25000...25000
  * Unit:  steps/second
  */
 void api_v()
 {
     int v[4] = {0, 0, 0, 0};
-    for (int i = 0; i < 4; i++)
+    for (int wheel = 0; wheel < 4; wheel++)
     {
         char *value = serialCommand.next();
         if (value == NULL)
@@ -73,11 +73,11 @@
             Serial.println("!E01: Not enough arguments supplied.");
             return;
         }
-        v[i] = atoi(value);
+        v[wheel] = atoi(value);
     }

-    for (int i = 0; i < 4; i++)
+    for (int wheel = 0; wheel < 4; wheel++)
     {
-        robot_setMotorSpeed(i, v[i]);
+        robot_setMotorSpeed(wheel, v[wheel]);
     }
 }


Update bus_reader.ino

Update bus_reader.ino

--- arduino/bus_reader/bus_reader.ino
+++ arduino/bus_reader/bus_reader.ino
@@ -2,7 +2,7 @@
 #include <boards.h>
 #include <RBL_nRF8001.h>

-#include <LiquidCrystal.h> //Replaces the LiquidCrystal.h
+#include <LiquidCrystal.h>
 #include <EEPROM.h>
 #include <Wire.h>


add start button

add start button

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -14,7 +14,11 @@
 #define SERIALDEV Serial
 #endif

+#define START_BUTTON_DEBOUNCE_TIME_MS        250
+
 #define TEENSY_LED          13
+#define START_BUTTON        14
+
 #define IR_LEFT             A9
 #define IR_RIGHT            A8
 #define IR_FRONT_LEFT       A7
@@ -42,8 +46,11 @@
 Servo drivingservo;

 bool m_automatic = false;
+uint32_t last_time = 0;

-uint32_t last_time = 0;
+bool m_button_press = false;
+bool m_button_active = false;
+bool m_last_button_time = 0;

 MCDriver driver;

@@ -63,7 +70,18 @@
 	analogReadResolution(10);
 	pinMode(TEENSY_LED, OUTPUT);

+	pinMode(START_BUTTON, INPUT_PULLUP);
+	attachInterrupt(START_BUTTON, button_service, FALLING);
+
 	telemetry.header = BC_TELEMETRY;
+}
+
+void button_service() {
+	if (m_button_active) {
+		m_button_press = true;
+		m_button_active = false;
+		m_last_button_time = millis();
+	}
 }

 void toggle_led() {
@@ -79,6 +97,16 @@
 }

 void loop() {
+	if (m_button_press) {
+		m_button_press = false;
+		m_automatic = true;
+	}
+
+	// handle debounce
+	if (!m_button_active && ((millis() - m_last_button_time) > START_BUTTON_DEBOUNCE_TIME_MS)) {
+		m_button_active = true;
+	}
+
 	while (SERIALDEV.available() > 0) {
 		m_rx_len = hdlc.decode(SERIALDEV.read());


Minor changes to firmware.

Minor changes to firmware.

--- firmware/firmware.ino
+++ firmware/firmware.ino
@@ -17,7 +17,7 @@
 char url[] = "http://senseplatypus.com";

 USBHost Usb;
-ADK adk(&Usb, companyName, applicationName, accessoryName,versionNumber, url, serialNumber);
+ADK adk(&Usb, companyName, applicationName, accessoryName, versionNumber, url, serialNumber);

 // Android receive buffer
 const size_t RECEIVE_BUFFER_SIZE = 512;


LoaderTest: Command prompt

LoaderTest: Command prompt

- Command loop
- Detect if Gigatron is active or not
- Attempting some sort of application level flow control for incoming
  object files over the USB port. (No sending written yet)

I don't like doing this, but it appears there is no flow control
for serial data coming into the Arduino over the USB interface.
Application level flow control is then needed because receiving
serial data can't happen in parallel with sending data: Receiving
REQUIRES interrupts. Sending FORBIDS interrupts.

My only future hope for eliminating this is reprogramming the
"support AVR" on the board (ATMEGA8U2-MU), and add buffering and
flow control there.

--- LoaderTest/LoaderTest.ino
+++ LoaderTest/LoaderTest.ino
@@ -1,8 +1,8 @@

 // Concept tester for loading programs into the
 // Gigatron TTL microcomputer
-// Marcel van Kervinck
-// Jan 2018
+// Marcel van Kervinck / Chris Lord
+// May 2018

 // The object file is embedded (in PROGMEM) in GT1 format. It would be
 // GREAT if we can find a way to receive the file over the Arduino's
@@ -30,47 +30,109 @@

 byte checksum; // Global is simplest

-void setup() {
+void setup()
+{
   // Enable output pin (pins are set to input by default)
   PORTB |= 1<<PORTB5; // Send 1 when idle
   DDRB = 1<<PORTB5;

   // Open upstream communication
-  Serial.begin(57600);
+  Serial.begin(9600);
   doVersion();

   // In case we power on together with the Gigatron, this is a
   // good pause to wait for the video loop to have started
   delay(350);
+
+  prompt();
 }

 void loop()
 {
-  doLoad();
-  countdown(10);
+  static char line[20];
+  static byte lineIndex = 0;
+
+  if (Serial.available()) {
+    byte next = Serial.read();
+    if (lineIndex < sizeof line)
+      line[lineIndex++] = next;
+    if (next == '\n') {
+      line[lineIndex-1] = '\0';
+      doCommand(line);
+      lineIndex = 0;
+    }
+  }
+}
+
+void prompt()
+{
+  Serial.println(detectGigatron() ? ":Gigatron OK" : "!Gigatron offline");
+  Serial.println("\nCmd?");
+}
+
+bool detectGigatron()
+{
+  unsigned long timeout = millis() + 200;
+  int mask = 0xf;
+
+  while (mask != 0 && millis() < timeout) {
+    int state = (PINB >> PORTB3) & 3; // capture PORTB3 and PORTB4
+    mask &= ~(1 << state);
+  }
+
+  return mask ? false : true;
+}
+
+void doCommand(char line[])
+{
+  switch (toupper(line[0])) {
+  case 'V': doVersion();         break;
+  case 'R': doReset();           break;
+  case 'L': doLoader();          break;
+  case 'P': doTransfer(gt1File); break;
+  case 'U': doTransfer(NULL);    break;
+  case 'H': doHelp();            break;
+  case 0:                        break;
+  default:  Serial.println("!Unknown command (type 'H' for help)");
+  }
+  prompt();
 }

 void doVersion()
 {
-  Serial.println("*** Arduino Gigatron Extender");
+  Serial.println(":Gigatron Interface Adapter [Arduino]");
+}
+
+void doHelp()
+{
+  Serial.println(":Commands are");
+  Serial.println(":V   Show version");
+//Serial.println(":E0  Echo off");
+//Serial.println(":E1  Echo on");
+  Serial.println(":R   Reset Gigatron");
+  Serial.println(":L   Start Loader");
+  Serial.println(":P   Transfer object file from PROGMEM");
+  Serial.println(":U   Transfer object file from USB");
+  Serial.println(":H   Show this help");
 }

 void doReset()
 {
   // Soft reset: hold start for >128 frames (>2.1 seconds)
-  Serial.println("Reset Gigatron");
+  Serial.println(":Resetting Gigatron");
+  Serial.flush();
+
   sendController(~buttonStart, 128+32);

   // Wait for main menu to be ready
   delay(1500);
 }

-void doLoad()
-{
-  doReset();
-
+void doLoader()
+{
   // Navigate menu. 'Loader' is at the bottom
-  Serial.println("Start Loader from menu");
+  Serial.println(":Starting Loader from menu");
+  Serial.flush();
   for (int i=0; i<10; i++) {
     sendController(~buttonDown, 2);
     delay(50);
@@ -81,21 +143,6 @@

   // Wait for Loader to be running
   delay(1000);
-
-  // Send GT1 file
-  Serial.println("Send GT1 file");
-  sendGt1File(gt1File);
-}
-
-// Countdown from n to 1
-void countdown(int n)
-{
-  for (int i=n; i>0; i--) {
-    Serial.print(" ");
-    Serial.print(i);
-    delay(1000);
-  }
-  Serial.print("\n");
 }

 // Because the Arduino doesn't have enough RAM to buffer
@@ -104,55 +151,95 @@
 // concatenated frames to the Gigatron. Between segments
 // it is communicating upstream with the serial port.

-void sendGt1File(const byte *gt1)
-{
-  #define readNext() pgm_read_byte(gt1++)
-
-  byte segment[300] = {0};
-  word address = readNext();
+void doTransfer(const byte *gt1)
+{
+  int nextByte;
+
+  #define readNext() {\
+    nextByte = gt1 ? pgm_read_byte(gt1++) : nextSerial();\
+    if (nextByte < 0) return;\
+  }
+
+  #define ask(n)\
+    if (!gt1) {\
+      Serial.print(n);\
+      Serial.println("?");\
+    }
+
+  byte segment[300] = {0}; // Multiple of N for padding
+
+  ask(3);
+  readNext();
+  word address = nextByte;

   // Any number n of segments (n>0)
   do {
     // Segment start and length
-    address = (address << 8) + readNext();
-    int len = readNext();
-    if (!len)
-      len = 256;
+    readNext();
+    address = (address << 8) + nextByte;
+    readNext();
+    int len = nextByte ? nextByte : 256;
+
+    ask(len);

     // Copy data into send buffer
-    for (int i=0; i<len; i++)
-      segment[i] = readNext();
+    for (int i=0; i<len; i++) {
+      readNext();
+      segment[i] = nextByte;
+    }

     // Check that segment doesn't cross the page boundary
     if ((address & 255) + len > 256) {
-      Serial.println("? Invalid GT1 data");
+      Serial.println("!Data error (page overflow)");
       return;
     }

     // Send downstream
-    Serial.print("> Load $");
-    Serial.print(address, HEX);
-    Serial.print(" (");
+    Serial.print(":Loading ");
     Serial.print(len);
-    Serial.println(" bytes)");
+    Serial.print(" bytes at $");
+    Serial.println(address, HEX);
+    Serial.flush();
+
     sendGt1Segment(address, len, segment);

-    address = readNext();
+    // Signal that we're ready to receive more
+    ask(3);
+    readNext();
+    address = nextByte;
+
   } while (address != 0);

-  // Read start address
-  address = readNext();
-  address = (address << 8) + readNext();
+  // Two bytes for start address
+  readNext();
+  address = nextByte;
+  readNext();
+  address = (address << 8) + nextByte;
   if (address != 0) {
-    Serial.print("> Start $");
+    Serial.print(":Executing from $");
     Serial.println(address, HEX);
-    sendGt1Execute(address, NULL);
-  }
+    Serial.flush();
+    sendGt1Execute(address, segment+240);
+  }
+}
+
+int nextSerial()
+{
+  unsigned long timeout = millis() + 5000;
+
+  while (!Serial.available() && millis() < timeout)
+    ;
+
+  int nextByte = Serial.read();
+  if (nextByte < 0)
+    Serial.println("!Timeout error (no data)");
+
+  return nextByte;
 }

 // Send a 1..256 byte code or data segment into the Gigatron by
 // repacking it into Loader frames of max N=60 payload bytes each.
-void sendGt1Segment(word address, int len, const byte data[])
+void sendGt1Segment(word address, int len, byte data[])
 {
   noInterrupts();
   byte n = min(N, len);
@@ -167,7 +254,7 @@
 }

 // Send execute command
-void sendGt1Execute(word address, const byte data[])
+void sendGt1Execute(word address, byte data[])
 {
   noInterrupts();
   resetChecksum(0, address, data);
@@ -191,18 +278,18 @@
   interrupts(); // So delay() can work again
 }

-void resetChecksum(byte n, word address, const byte *data)
+void resetChecksum(byte n, word address, byte dummyData[])
 {
   // Send one frame with false checksum to force
   // a checksum resync at the receiver
   checksum = 0;
-  sendFrame(-1, n, address, data);
+  sendFrame(-1, n, address, dummyData);

   // Setup checksum properly
   checksum = 'g';
 }

-void sendFrame(byte firstByte, byte len, word address, const byte *message)
+void sendFrame(byte firstByte, byte len, word address, byte message[])
 {
   // Send one frame of data
   //


More scales

More scales

--- examples/cvseq_test/cvseq_test.ino
+++ examples/cvseq_test/cvseq_test.ino
@@ -5,7 +5,7 @@
 #define OUT_PIN_2 5
 #define TEMPO_PIN 2

-#define OCTAVES 1
+#define OCTAVES 3

 /*
     To play around with the Sequencer, wire a photo resitor to A0
@@ -32,7 +32,27 @@

 // ^^^ #include <werkstatt.h> ^^^

-int scale[] = {tonic, major2nd, major3rd, fourth, fifth, major6th, major7th};
+// Major
+// int scale[] = {tonic, major2nd, major3rd, fourth, fifth, major6th, major7th};
+
+// Minor
+// int scale[] = {tonic, major2nd, minor3rd, fourth, fifth, minor6th, minor7th};
+
+// Dorian
+// int scale[] = {tonic, major2nd, minor3rd, fourth, fifth, major6th, minor7th};
+
+// Phrygian
+// int scale[] = {tonic, minor2nd, minor3rd, fourth, fifth, minor6th, minor7th};
+
+// Locrian
+// int scale[] = {tonic, minor2nd, minor3rd, fourth, tritone, minor6th, minor7th};
+
+// Major Pentatonic (Jazz)
+//int scale[] = {tonic, major2nd, major3rd, fifth, major6th};
+
+// Blues
+int scale[] = {tonic, major2nd, minor3rd, fourth, fifth, major6th, minor7th};
+
 int scale_size = sizeof(scale)/sizeof(int);
 // Repeat scale OCTAVES times, plus one note to end on tonic
 int idx_range = (scale_size * OCTAVES) + 1;


Update allinline.ino

Update allinline.ino

--- allinline/allinline.ino
+++ allinline/allinline.ino
@@ -21,8 +21,8 @@

 Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIVIDER);

-#define WLAN_SSID       "CL Eng Devices" // supersecret - hide before checkin...
-#define WLAN_PASS       "mak3 all the Things talk" // hide this too.
+#define WLAN_SSID       "SSID NAME" // supersecret - hide before checkin...
+#define WLAN_PASS       "SUPERSECRET" // hide this too.
 #define WLAN_SECURITY   WLAN_SEC_WPA2
 // #define LISTEN_PORT     7


update motion

update motion


removed a debug Serial.print

removed a debug Serial.print

--- Servorator16.ino
+++ Servorator16.ino
@@ -79,7 +79,6 @@
 void update_servo( SS_Index servo, SS_Angle angle, void *data)
 {
   // angles are in tenths of degrees so 180 degrees is actually 1800
-  Serial.println(angle/10);
   // 4096 ticks is 20,000 us (50Hz)
   // Angle 0 is 500 us
   // angle 1800 is 2,500 us


modify display

modify display


[LedDude] Implemented lock on Analog0.

[LedDude] Implemented lock on Analog0.

Signed-off-by: Juri Berlanda <5bfdca9e82c53adb0603ce7083f4ba4f2da5cacf@hotmail.com>

--- laundry-dude-led-sensor/laundry-dude-led-sensor.ino
+++ laundry-dude-led-sensor/laundry-dude-led-sensor.ino
@@ -38,8 +38,16 @@
   Serial.begin(SERIAL_BAUDRATE);
   xbeeSerial.begin(SERIAL_BAUDRATE);

+  // Setup lock
+  pinMode(A0, OUTPUT);
+  setLockState(false);
+
   // Setup Accelerometer
   initMpu();
+}
+
+void setLockState(bool locked) {
+  digitalWrite(A0, locked);
 }

 void loop() {
@@ -54,9 +62,21 @@
     case 'a':
       xbeeSerial.print("a=");xbeeSerial.println(aaWorld.x + aaWorld.y + aaWorld.z);
       break;
+    case 'b':
+      while (!xbeeSerial.available());
+      switch (xbeeSerial.read()) {
+        case '1':
+          setLockState(true);
+          break;
+        case '0':
+          setLockState(false);
+          break;
+      }
+      while (xbeeSerial.available())
+        xbeeSerial.read();
+      break;
     }
-  } else
-    delay(FETCH_INTERVAL);
+  }
 }

 void readLightsensor() {