Add an emulator

Add an emulator

const int MAXTIME = 400;
const int bSize = 20;
char buffer[bSize];
int ByteCount;

void setup () {
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  Serial.setTimeout(MAXTIME);
  memset(buffer, 0, bSize);
}

void loop () {
  if (Serial.available()) {
    ByteCount = -1;
    ByteCount = Serial.readBytesUntil( '\n', buffer, bSize); // We are expecting \r\n closing
    if(ByteCount > 0) {
      //Serial.println(ByteCount, DEC);
      if(strcmp( buffer, "AX:T?\r") == 0 ) Serial.println("XA:B0002");
      else if(strcmp( buffer, "AX:N?\r") == 0 ) Serial.println("XA:T0010");
      else if(strcmp( buffer, "AX:B?\r") == 0 ) Serial.println("XA:T0012");
      else if(strcmp( buffer, "AX:NU\r") == 0 ) Serial.println("XA:OK");
      else if(strcmp( buffer, "AX:TA\r") == 0 ) Serial.println("XA:OK");
      else if(strcmp( buffer, "AX:BR\r") == 0 ) Serial.println("XA:OK");
      else if(strcmp( buffer, "AX:NT\r") == 0 ) Serial.println("XA:OK");
      else if(strcmp( buffer, "AX:TR\r") == 0 ) Serial.println("XA:OK");
      else Serial.println("XA:NACK");
      Serial.flush();
      memset(buffer, 0, bSize);
    }
  }
  delay(10);
}

error: pathspec 'arduino_balance_response/arduino_balance_response.ino' did not match any file(s) known to git


deck arduino sketch

deck arduino sketch

#include "DHT.h"

#include <stdlib.h>
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"

#define	DHTPIN	2
#define DHTTYPE	DHT22

#define LOOP_DELAY	60000

#define IDLE_TIMEOUT_MS  30000

// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ   3  // MUST be an interrupt pin!
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10
// Use hardware SPI for the remaining pins
// On an UNO, SCK = 13, MISO = 12, and MOSI = 11
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIVIDER); // you can change this clock speed but DI

#define WLAN_SSID       "flypaper"        // cannot be longer than 32 characters!
#define WLAN_PASS       "IamIthinkIwill"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2

#define REST_SERVER_PORT	9000

DHT dht(DHTPIN, DHTTYPE);

void setup() {
	Serial.begin(115200);
	Serial.println(F("Initializing..."));

	// Serial.println("");
	// Serial.print("Starting DHT sensor...");
	dht.begin();
	// Serial.println("done.");

	// Serial.println("");
	// Serial.println("Initializing the CC3000...");
	if (!cc3000.begin()) {
		Serial.println(F("CC3000 initialization failed"));
	} else {
		// uint16_t firmware = checkCc3000FirmwareVersion();
		// if (firmware < 0x113) {
		// 	Serial.println(F("Wrong firmware version!"));
		// }

  	// displayCc3000MACAddress();

		// Serial.println(F("\nDeleting old connection profiles"));
		if (!cc3000.deleteProfiles()) {
			Serial.println(F("Could not delete old connection profiles!"));
		}

		char *ssid = WLAN_SSID;             /* Max 32 chars */
		Serial.print(F("\nAttempting to connect to ")); Serial.println(ssid);

		if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
			Serial.println(F("Failed!"));
		} else {
			Serial.println("Connected!");
		}

		// Serial.println(F("Request DHCP"));
		while (!cc3000.checkDHCP()) {
			delay(100); // ToDo: Insert a DHCP timeout!
		}

		while (! displayCc3000ConnectionDetails()) {
			delay(1000);
		}

		// Serial.println("Done.");
	}

	Serial.println(F("\r\nInitialization complete\r\n"));
}

void loop() {

	readDht();

  delay(LOOP_DELAY);
}

void readDht() {
	float humidity = dht.readHumidity();

	if (isnan(humidity)) {
		Serial.println(F("Failed to read humidity from DHT22"));
	} else {
		// Serial.print("Humidity: ");
		// Serial.println(humidity);
    sendData(humidity, "percent-humidity", "DHT22");
	}

	float temperatureCelcius = dht.readTemperature();

	if (isnan(temperatureCelcius)) {
		Serial.println(F("Failed to read temperature from DHT22"));
	} else {
		// Serial.print("Temperature: ");
		// Serial.print(temperatureCelcius);
		// Serial.println(" degrees Celcius");
    sendData(temperatureCelcius, "degrees-celcius", "DHT22");
	}
}

/**************************************************************************/
/*!
    @brief  Tries to read the CC3000's internal firmware patch ID
*/
/**************************************************************************/
// uint16_t checkCc3000FirmwareVersion(void)
// {
//   uint8_t major, minor;
//   uint16_t version;

// #ifndef CC3000_TINY_DRIVER
//   if(!cc3000.getFirmwareVersion(&major, &minor))
//   {
//     Serial.println(F("Unable to retrieve the firmware version!\r\n"));
//     version = 0;
//   }
//   else
//   {
//     Serial.print(F("Firmware V. : "));
//     Serial.print(major); Serial.print(F(".")); Serial.println(minor);
//     version = major; version <<= 8; version |= minor;
//   }
// #endif
//   return version;
// }

/**************************************************************************/
/*!
    @brief  Tries to read the 6-byte MAC address of the CC3000 module
*/
/**************************************************************************/
// void displayCc3000MACAddress(void)
// {
//   uint8_t macAddress[6];

//   if(!cc3000.getMacAddress(macAddress))
//   {
//     Serial.println(F("Unable to retrieve MAC Address!\r\n"));
//   }
//   else
//   {
//     Serial.print(F("MAC Address : "));
//     cc3000.printHex((byte*)&macAddress, 6);
//   }
// }

/**************************************************************************/
/*!
    @brief  Tries to read the IP address and other connection details
*/
/**************************************************************************/
bool displayCc3000ConnectionDetails(void)
{
  uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;

  if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
  {
    Serial.println(F("Unable to retrieve the IP Address!\r\n"));
    return false;
  }
  else
  {
    Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
    Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask);
    Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway);
    Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
    Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
    Serial.println();
    return true;
  }
}

void sendData(float data, String uom, String sensor) {
  char dataBuffer[10];
  dtostrf(data, 3, 4, dataBuffer);

  sendData(
    "{\"value\":" +
    String(dataBuffer) +
    ",\"uom\":\"" +
    uom +
    "\",\"sensor\":\"" +
    sensor +
    "\",\"source\":\"deck-arduino\"}");
}

void sendData(String msg) {

  Serial.println(msg);
  Serial.println();

	uint32_t ip = 0;

	ip = cc3000.IP2U32(192, 168, 1, 65);

	// Serial.print(F("\n\rConnecting... ")); cc3000.printIPdotsRev(ip); Serial.print("...");

	Adafruit_CC3000_Client www = cc3000.connectTCP(ip, REST_SERVER_PORT);
  if (www.connected()) {
    // headers
    www.fastrprint(F("POST ")); www.fastrprint(F("/1/reading")); www.fastrprint(F(" HTTP/1.1\r\n"));
    www.fastrprint(F("Host: firefly:9000\r\n"));
    www.fastrprint(F("Content-Type: application/json\r\n"));
    www.fastrprint(F("Cache-Control: no-cache\r\n"));
    www.fastrprint(F("Content-Length: "));
    www.print(msg.length());
    www.fastrprint(F("\r\n"));
    www.fastrprint(F("Connection: close\r\n"));
    www.fastrprint(F("\r\n"));

    // body
    www.print(msg);
    www.fastrprint(F("\r\n"));
    www.println();

    Serial.println();
  } else {
    Serial.println(F("\r\nConnection failed\r\n"));
    return;
  }

  unsigned long lastRead = millis();
  while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
    while (www.available()) {
      char c = www.read();
      Serial.print(c);
      lastRead = millis();
    }
  }

  // Serial.println(F("\r\n-------------------------------------\r\n\r\n"));

  /* You need to make sure to clean up after yourself or the CC3000 can freak out */
  /* the next time your try to connect ... */
  www.close();
  // Serial.println(F("-------------------------------------"));
  // Serial.println(F("\n\nDisconnecting"));
  // cc3000.disconnect();
}
//28358
//26186

error: pathspec 'arduino/deck-arduino/deck-arduino.ino' did not match any file(s) known to git


sample file

sample file

#include <ITimeSource .h>
#include <NtpPacket.h>
#include <NtpServer.h>

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

error: pathspec 'examples/basic/basic.ino' did not match any file(s) known to git


Here goes Morse Advanced...

Here goes Morse Advanced...

/*
  Morse Advanced
  Input any phrase, translate it to International Morse code (American is obsolete
  so I figured I'd just go with International), and output to LED. My Morse Code
  reference:  http://en.wikipedia.org/wiki/Morse_code
 */

// Set time unit, dit and dah... (in mS)
int time_unit = 150; //don't really need this but it's a bit more elegant this way I think
int dit = time_unit;
int dah = time_unit*3;

// Pin 13 has an LED connected on most Arduino boards.
// give it a name) {
int led = 13;

// Set Phrase to 'translate'
// only use all caps and no punctuation (because I'm lazy);
char myPhrase[ ] = "WHAT HATH GOD WROUGHT";
int loopA; // counters for the various loops
int loopB;
int loopC;
int repeat_dot; // counters for dot and dash repetitions
int repeat_dash;
char x; // this stores the *next* character in the string, to determine how long of a gap

void setup() {
  // initialize the digital pin as an output.
  Serial.begin(9600);
  pinMode(led, OUTPUT);
}

void loop() {
    Serial.print("TOP OF LOOP \n");
    loopA = 0;
    while (loopA < sizeof(myPhrase)+1) {
      Serial.println("Loop number "); // All serial.print functions are for debugging in the serial monitor
      Serial.print(loopA);
      Serial.print("\n Character in this loop: ");
      Serial.print(myPhrase[loopA]);
      if (myPhrase[loopA]!=' ') { // So that functions morse and gap to run for spaces between words
      morse(myPhrase[loopA]);
      gap(myPhrase[loopA+1]);
      }
      loopA++;
    }
}

void dot(int repeat_dot) {
  for (loopB = 0; loopB < repeat_dot; loopB++) {
    Serial.println("dot");
    digitalWrite(led, HIGH);
    delay(dit);
    digitalWrite(led,LOW);
    delay(dit);
  }
}

void dash(int repeat_dash) {
  for (loopC = 0; loopC < repeat_dash; loopC++) {
    Serial.println("dash");
    digitalWrite(led,HIGH);
    delay(dah);
    digitalWrite(led,LOW);
    delay(dit);
    }
}

void gap(char x) {
       Serial.println("function gap called");
 if (x==' ') {
     delay(time_unit*6); // six not seven because one time_unit delay is build into the dash and dot functions
     Serial.println("delay seven");
     }
     else if (x=='\0') { // delay for end of phrase
       delay(time_unit*9);
       Serial.println("delay nine");
     }
     else {
        Serial.println("delay three");
        delay(time_unit*2); //only two since one time_unit delay is built in to the dash and dot functions
     }
}

void morse(char x) {
  Serial.println("\n function morse called");
  if (x=='A') {
      dot(1);
      dash(1);
      }
    else if (x=='B') {
      dash(1);
      dot(3);
      }
    else if (x=='C') {
      dash(1);
      dot(1);
      dash(1);
      dot(1);
      }
    else if (x=='D') {
      dash(1);
      dot(2);
      }
    else if (x=='E') {
      dot(1);
      }
    else if (x=='F') {
      dot(2);
      dash(1);
      dot(1);
      }
    else if (x=='G') {
      dash(2);
      dot(1);
      }
    else if (x=='H') {
      dot(4);
      }
    else if (x=='I') {
      dot(2);
      }
    else if (x=='J') {
      dot(1);
      dash(3);
      }
    else if (x=='K') {
      dash(1);
      dot(1);
      dash(1);
      }
    else if (x=='L') {
      dot(1);
      dash(1);
      dot(2);
      }
    else if (x=='M') {
      dash(2);
      }
    else if (x=='N') {
      dash(1);
      dot(1);
      }
    else if (x=='O') {
      dash(3);
      }
    else if (x=='P') {
      dot(1);
      dash(2);
      dot(1);
      }
    else if (x=='Q') {
      dash(2);
      dot(1);
      dash(1);
      }
    else if (x=='R') {
      dot(1);
      dash(1);
      dot(1);
      }
    else if (x=='S') {
      dot(3);
      }
    else if (x=='T') {
      dash(1);
      }
    else if (x=='U') {
      dot(2);
      dash(1);
      }
    else if (x=='V') {
      dot(3);
      dash(1);
      }
    else if (x=='W') {
      dot(1);
      dash(2);
      }
    else if (x=='X') {
      dash(1);
      dot(2);
      dash(1);
      }
    else if (x=='Y') {
      dash(1);
      dot(1);
      dash(2);
      }
    else if (x=='Z') {
      dash(2);
      dot(2);
      }
   }

error: pathspec 'people/abrahamavnisan/Week4/Arduino/MorseAdvanced.ino' did not match any file(s) known to git


Create MRLCommOculus4.ino

Create MRLCommOculus4.ino

/**
*
* @author GroG (at) myrobotlab.org
*
* This file is part of MyRobotLab.
*
* Enjoy !
*
* MRLComm.ino
* -----------------
* Purpose: support servos, sensors, analog & digital polling
* oscope, motors, range sensors, pingdar & steppers.
*
* Requirements: MyRobotLab running on a computer & a serial connection
*
* FIXME - find "easiest" way to upload a single hex file !!! command line example
* perhaps avrdude ?
*
*/

#include <Servo.h>
#define MRLCOMM_VERSION				24

// serial protocol functions
#define MAGIC_NUMBER  					170 // 10101010

// ----- MRLCOMM FUNCTION GENERATED INTERFACE BEGIN -----------
///// INO GENERATED DEFINITION BEGIN //////
// {publishMRLCommError Integer}
#define PUBLISH_MRLCOMM_ERROR		1

// {getVersion}
#define GET_VERSION		2

// {publishVersion Integer}
#define PUBLISH_VERSION		3

// {analogReadPollingStart Integer}
#define ANALOG_READ_POLLING_START		4

// {analogReadPollingStop Integer}
#define ANALOG_READ_POLLING_STOP		5

// {analogWrite Integer Integer}
#define ANALOG_WRITE		6

// {digitalReadPollingStart Integer}
#define DIGITAL_READ_POLLING_START		7

// {digitalReadPollingStop Integer}
#define DIGITAL_READ_POLLING_STOP		8

// {digitalWrite Integer Integer}
#define DIGITAL_WRITE		9

// {motorAttach String String Integer Integer Integer}
#define MOTOR_ATTACH		10

// {motorDetach String}
#define MOTOR_DETACH		11

// {motorMove String}
#define MOTOR_MOVE		12

// {motorMoveTo String double}
#define MOTOR_MOVE_TO		13

// {pinMode Integer Integer}
#define PIN_MODE		14

// {publishCustomMsg Object[]}
#define PUBLISH_CUSTOM_MSG		15

// {publishLoadTimingEvent Long}
#define PUBLISH_LOAD_TIMING_EVENT		16

// {publishPin Pin}
#define PUBLISH_PIN		17

// {publishPulse Integer}
#define PUBLISH_PULSE		18

// {publishSensorData SensorData}
#define PUBLISH_SENSOR_DATA		19

// {publishServoEvent Integer}
#define PUBLISH_SERVO_EVENT		20

// {publishStepperEvent Integer}
#define PUBLISH_STEPPER_EVENT		21

// {publishTrigger Pin}
#define PUBLISH_TRIGGER		22

// {pulseIn int int int String}
#define PULSE_IN		23

// {sensorAttach String}
#define SENSOR_ATTACH		24

// {sensorPollingStart String int}
#define SENSOR_POLLING_START		25

// {sensorPollingStop String}
#define SENSOR_POLLING_STOP		26

// {servoAttach String Integer}
#define SERVO_ATTACH		27

// {servoDetach Servo}
#define SERVO_DETACH		28

// {servoSweepStart String int int int}
#define SERVO_SWEEP_START		29

// {servoSweepStop String}
#define SERVO_SWEEP_STOP		30

// {servoWrite String Integer}
#define SERVO_WRITE		31

// {servoWriteMicroseconds String Integer}
#define SERVO_WRITE_MICROSECONDS		32

// {setDebounce int}
#define SET_DEBOUNCE		33

// {setDigitalTriggerOnly Boolean}
#define SET_DIGITAL_TRIGGER_ONLY		34

// {setLoadTimingEnabled boolean}
#define SET_LOAD_TIMING_ENABLED		35

// {setPWMFrequency Integer Integer}
#define SET_PWMFREQUENCY		36

// {setSampleRate int}
#define SET_SAMPLE_RATE		37

// {setSerialRate int}
#define SET_SERIAL_RATE		38

// {setServoEventsEnabled String boolean}
#define SET_SERVO_EVENTS_ENABLED		39

// {setServoSpeed String Float}
#define SET_SERVO_SPEED		40

// {setStepperSpeed Integer}
#define SET_STEPPER_SPEED		41

// {setTrigger int int int}
#define SET_TRIGGER		42

// {softReset}
#define SOFT_RESET		43

// {stepperAttach Stepper}
#define STEPPER_ATTACH		44

// {stepperDetach String}
#define STEPPER_DETACH		45

// {stepperMoveTo String int int}
#define STEPPER_MOVE_TO		46

// {stepperReset String}
#define STEPPER_RESET		47

// {stepperStop String}
#define STEPPER_STOP		48

// {stopService}
#define STOP_SERVICE		49

///// INO GENERATED DEFINITION END //////

// ----- MRLCOMM FUNCTION GENERATED INTERFACE END -----------

#define STEPPER_TYPE_SIMPLE  			1

// ------ event types ------
#define STEPPER_EVENT_STOP				1
#define STEPPER_EVENT_STEP				2

// servo event types
#define  SERVO_EVENT_STOPPED			1
#define  SERVO_EVENT_POSITION_UPDATE 	2

// error types
#define ERROR_SERIAL					1
#define ERROR_UNKOWN_CMD				2
#define ERROR_ALREADY_EXISTS			3
#define ERROR_DOES_NOT_EXIST			4

// ------ error types ------
#define SENSOR_ULTRASONIC				1

#define CUSTOM_MSG						50

// need a method to identify type of board
// http://forum.arduino.cc/index.php?topic=100557.0

#define COMMUNICATION_RESET	   252
#define SOFT_RESET			   253
#define NOP  				   255

// ----------  MRLCOMM FUNCTION INTERFACE END -----------

// MAX definitions
// MAX_SERVOS defined by boardtype/library
#define PINGDARS_MAX		6
#define SENSORS_MAX			12
#define STEPPERS_MAX		6

#define MAX_MOTORS 10

#define ECHO_STATE_START 1
#define ECHO_STATE_TRIG_PULSE_BEGIN 2
#define ECHO_STATE_TRIG_PULSE_END 3
#define ECHO_STATE_MIN_PAUSE_PRE_LISTENING 4
#define ECHO_STATE_LISTENING 5
#define ECHO_STATE_GOOD_RANGE	6
#define ECHO_STATE_TIMEOUT	7

// --VENDOR DEFINE SECTION BEGIN--
// --VENDOR DEFINE SECTION END--

// FIXME FIXME FIXME
// -- FIXME - modified by board type BEGIN --
// Need Arduino to do a hardware abstraction layer
// https://code.google.com/p/arduino/issues/detail?id=59
// AHAAA !! - many defintions in - pins_arduino.h !!!
// Need a "board" identifier at least !!!

#define ANALOG_PIN_COUNT 16 // mega
#define DIGITAL_PIN_COUNT 54 // mega
// #define MAX_SERVOS 48 - is defined @ compile time !!
// -- FIXME - modified by board type END --

#define ARDUINO_TYPE_INT 16; // :) type identifier - not size - but what the hell ;)

/*
* TODO - CRC for last byte
* getCommand - retrieves a command message
* inbound and outbound messages are the same format, the following represents a basic message
* format
*
* MAGIC_NUMBER|NUM_BYTES|FUNCTION|DATA0|DATA1|....|DATA(N)
*              NUM_BYTES - is the number of bytes after NUM_BYTES to the end
*
*/

int msgSize = 0; // the NUM_BYTES of current message

unsigned int debounceDelay = 50; // in ms
long lastDebounceTime[DIGITAL_PIN_COUNT];
byte msgBuf[64];

typedef struct
  {
      int type;
      int trigPin;
      int echoPin;
      bool isRunning;
      int timeoutUS;
      unsigned long ts;
      unsigned long lastValue;
      int state;
      //NewPing* ping;
  }  sensor_type;

sensor_type sensors[SENSORS_MAX];

typedef struct
  {
  	  int ts;
      int type;
      int index; // is this redundant?
      int currentPos;
      int targetPos;
      int speed;

      int dirPin;
      int stepPin;

	  // support up to 5 wire steppers
      int pin0;
      int pin1;
      int pin2;
      int pin3;
      int pin4;

  }  stepper_type;

stepper_type steppers[STEPPERS_MAX];

// Servos
typedef struct
{
    Servo* servo;
    int index; // index of this servo
    int speed;
    int targetPos;
    int currentPos;
    bool isMoving;

    int step; // affects speed usually 1

    // sweep related
    int min;
    int max;
    // int delay; - related to speed
    int increment;
    bool isSweeping;

    // event related
    bool eventsEnabled;
} servo_type;

servo_type servos[MAX_SERVOS];

// Motors
typedef struct
{
    int index; // index of this motor
    int speed;
    int targetPos;
    int currentPos;
    bool isMoving;

    int step; // affects speed usually 1

    // sweep related
    int min;
    int max;
    // int delay; - related to speed
    int increment;
    bool isSweeping;

    // event related
    bool eventsEnabled;
} motor_type;

motor_type motors[MAX_MOTORS];

unsigned long loopCount     = 0;
unsigned long lastMicros 	= 0;
int byteCount               = 0;
unsigned char newByte 		= 0;
unsigned char ioCmd[64];  // message buffer for all inbound messages
int readValue;

// FIXME - normalize with sampleRate ..
int loadTimingModulus = 1000;

boolean loadTimingEnabled = false;
unsigned long loadTime = 0;
// TODO - avg load time

unsigned int sampleRate = 1; // 1 - 65,535 modulus of the loopcount - allowing you to sample less

int digitalReadPin[DIGITAL_PIN_COUNT];        // array of pins to read from
int digitalReadPollingPinCount = 0;           // number of pins currently reading
int lastDigitalInputValue[DIGITAL_PIN_COUNT]; // array of last input values
bool digitalTriggerOnly	= false;      // send data back only if its different

int analogReadPin[ANALOG_PIN_COUNT];          // array of pins to read from
int analogReadPollingPinCount = 0;            // number of pins currently reading
int lastAnalogInputValue[ANALOG_PIN_COUNT];   // array of last input values
bool analogTriggerOnly = false;         // send data back only if its different

//---- data record definitions begin -----

// TODO - all well and good .. but you dont control Servo's data (yet)
// should have a struct for it too - contains all the data info you'd want to have
// in a servo - same with stepper

typedef struct
  {
      int servoIndex; // id of servo in servos array
      //int servoPos; in servo
      int sensorIndex;
      int sweepMin;
      int sweepMax;
      int step;
      bool isRunning; // needed ? - is combo of two
  }  pingdar_type;

pingdar_type pingdars[PINGDARS_MAX];
//===custom msg interface begin===
	byte customParams[256];
	int paramBuffIndex;
	int paramCnt;
//===custom msg interface end===

void sendServoEvent(servo_type& s, int eventType);
void sendStepperEvent(stepper_type& s, int eventType);
unsigned long getUltrasonicRange(sensor_type& sensor);
// void sendMsg ( int num, ... );

//---- data record definitions end -----

void append(const int& data) {
	++paramCnt;
	customParams[paramBuffIndex] = ARDUINO_TYPE_INT;
	customParams[++paramBuffIndex] = (byte)(data >> 8);
	customParams[++paramBuffIndex] = ((byte) data & 0xff);
	++paramBuffIndex;
}

void startMsg() {
}

void setup() {
	Serial.begin(57600);        // connect to the serial port

	softReset();

	// --VENDOR SETUP BEGIN--
	// --VENDOR SETUP END--
}

void sendMsg(){

	// unbox
	Serial.write(MAGIC_NUMBER);
	Serial.write(paramBuffIndex + 2); // = param buff size + FN + paramCnt
	//Serial.write(2); // = param buff size + FN + paramCnt
	Serial.write(CUSTOM_MSG);
	Serial.write(paramCnt);

	for (int i = 0; i < paramBuffIndex; ++i){
		Serial.write(customParams[i]);
	}

	paramCnt = 0;
	paramBuffIndex = 0;
}

void softReset()
{
	for (int i = 0; i < MAX_SERVOS - 1; ++i)
	{
                servo_type& s = servos[i];
		s.speed = 100;
                if (s.servo != 0){
		  s.servo->detach();
                }
	}

	for (int j = 0; j < DIGITAL_PIN_COUNT - 1; ++j)
	{
		pinMode(j, OUTPUT);
	}

	digitalReadPollingPinCount = 0;
	analogReadPollingPinCount = 0;
	loopCount = 0;

}

void setPWMFrequency (int address, int prescalar)
{
	int clearBits = 0x07;
	if (address == 0x25)
	{
		TCCR0B &= ~clearBits;
		TCCR0B |= prescalar;
	} else if (address == 0x2E)
	{
		TCCR1B &= ~clearBits;
		TCCR1B |= prescalar;
	} else if (address == 0xA1)
	{
		TCCR2B &= ~clearBits;
		TCCR2B |= prescalar;
	}

}

/**
 * checks the existance of the searched value in the array
 * - good for not adding to a dynamic list of values if it
 * already exists
 */
bool exists(int array[], int len, int searchValue){
	for (int i = 0; i < len; ++i)
	{
		if (searchValue == array[i])
		{
			return true;
		}
	}
	return false;
}

/**
 * adds new value to a pseudo dynamic array/list
 * if successful - if value already exists on list
 * sends back an error
 */
bool addNewValue(int array[], int& len, int addValue)
{
	if (!exists(array, len, addValue)){
		array[len] = addValue;
		++len;
		return true;
	} else {
		sendError(ERROR_ALREADY_EXISTS);
		return false;
	}
}

bool removeAndShift (int array [], int& len, int removeValue)
{
	if (!exists(array, len, removeValue)){
		sendError(ERROR_DOES_NOT_EXIST);
		return false;
	}

	int pos = -1;

	if (len == 0)
	{
		// "should" never happen
		// would be calling remove on an empty list
		// the error ERROR_DOES_NOT_EXIST - "should" be called
		return true;
	}

	// find position of value
	for (int i = 0; i < len; ++i)
	{
		if (removeValue == array[i])
		{
			pos = i;
			break;
		}
	}
	// if at the end just decrement size
	if (pos == len - 1)
	{
		--len;
		return true;
	}

	// if found somewhere else shift left
	if (pos < len && pos > -1)
	{
		for (int j = pos; j < len - 1; ++j)
		{
			array[j] = array[j+1];
		}
		--len;
	}

	return true;
}

boolean getCommand ()
{
	// handle serial data begin
	if (Serial.available() > 0)
	{
		// read the incoming byte:
		newByte = Serial.read();
		++byteCount;

		// checking first byte - beginning of message?
		if (byteCount == 1 && newByte != MAGIC_NUMBER)
		{
			sendError(ERROR_SERIAL);

			// reset - try again
			byteCount = 0;
			return false;
		}

		if (byteCount == 2)
		{
		   // get the size of message
		   // todo check msg < 64 (MAX_MSG_SIZE)
		   msgSize = newByte;
		}

		if (byteCount > 2) {
		  // fill in msg data - (2) headbytes -1 (offset)
		  ioCmd[byteCount - 3] = newByte;
		}

		// if received header + msg
		if (byteCount == 2 + msgSize)
		{
          return true;
		}
	} // if Serial.available

	return false;
}

void loop () {

	++loopCount;

	if (getCommand())
	{
		switch (ioCmd[0])
		{

		case DIGITAL_WRITE:{
			digitalWrite(ioCmd[1], ioCmd[2]);
			break;
		}

		case ANALOG_WRITE:{
			analogWrite(ioCmd[1], ioCmd[2]);
			break;
		}

		case PIN_MODE:{
			pinMode(ioCmd[1], ioCmd[2]);
			break;
		}

		case SERVO_ATTACH:{
			servo_type& s = servos[ioCmd[1]];
			s.index = ioCmd[1];
			if (s.servo == NULL){
				s.servo = new Servo();
			}
			s.servo->attach(ioCmd[2]);
			s.step = 1;
			s.eventsEnabled = false;
			break;
		}

		case SERVO_SWEEP_START:{
			servo_type& s = servos[ioCmd[1]];
			s.min = ioCmd[2];
			s.max = ioCmd[3];
			s.step = ioCmd[4];
			s.isMoving = true;
			s.isSweeping = true;
			break;
		}

		case SERVO_SWEEP_STOP:{
			servo_type& s = servos[ioCmd[1]];
			s.isMoving = false;
			s.isSweeping = false;
			break;
		}

		case SERVO_WRITE:{
			servo_type& s = servos[ioCmd[1]];
			if (s.speed == 100 && s.servo != 0)// move at regular/full 100% speed
			{
				s.targetPos = ioCmd[2];
				s.currentPos = ioCmd[2];
				s.isMoving = false;
				s.servo->write(ioCmd[2]);
				if (s.eventsEnabled) sendServoEvent(s, SERVO_EVENT_STOPPED);
			} else if (s.speed < 100 && s.speed > 0) {
				s.targetPos = ioCmd[2];
				s.isMoving = true;
			}
			break;
		}

		case PUBLISH_SERVO_EVENT:{
			servo_type& s = servos[ioCmd[1]];
			s.eventsEnabled = ioCmd[2];
			break;
		}

		case SET_LOAD_TIMING_ENABLED:{
			loadTimingEnabled = ioCmd[1];
			//loadTimingModulus = ioCmd[2];
			loadTimingModulus = 1000;
			break;
		}

		case SERVO_WRITE_MICROSECONDS:{
			// TODO - incorporate into speed control etc
			// normalize - currently by itself doesn't effect events
			// nor is it involved in speed control
			servo_type& s = servos[ioCmd[1]];
			if (s.servo != 0) {
				// 1500 midpoint
				s.servo->writeMicroseconds(ioCmd[2]);
			}

			break;
		}

		case SET_SERVO_SPEED:{
			// setting the speed of a servo
			servo_type& servo = servos[ioCmd[1]];
			servo.speed = ioCmd[2];
			break;
		}

		case SERVO_DETACH:{
			servo_type& s = servos[ioCmd[1]];
			if (s.servo != 0){
			  s.servo->detach();
			}
			break;
		}

		case SET_PWMFREQUENCY:{
			setPWMFrequency (ioCmd[1], ioCmd[2]);
			break;
		}

		case ANALOG_READ_POLLING_START:{
			int pin = ioCmd[1];
			addNewValue(analogReadPin, analogReadPollingPinCount, pin);
			break;
		}

		case ANALOG_READ_POLLING_STOP:{
			int pin = ioCmd[1];
			removeAndShift(analogReadPin, analogReadPollingPinCount, pin);
			break;
		}

		case DIGITAL_READ_POLLING_START:{
			int pin = ioCmd[1];
			addNewValue(digitalReadPin, digitalReadPollingPinCount, pin);
			break;
		}

		case DIGITAL_READ_POLLING_STOP:{
			int pin = ioCmd[1];
			removeAndShift(digitalReadPin, digitalReadPollingPinCount, pin);
			break;
		}

		case SET_TRIGGER:{
                        // FIXME !!! - you need 1. a complete pin list !!!   analog & digital should be defined by attribute not
                        // data structure !!!  if (pin.type == ??? if needed
			// TODO - if POLLING ALREADY DON'T RE-ADD - MAKE RE-ENTRANT
			analogReadPin[analogReadPollingPinCount] = ioCmd[1]; // put on polling read list
			++analogReadPollingPinCount;
			break;
		}

		case SET_DEBOUNCE:{
			// default debounceDelay = 50;
			debounceDelay = ((ioCmd[1]<<8) + ioCmd[2]);
			break;
		}

		case SET_DIGITAL_TRIGGER_ONLY:{
			digitalTriggerOnly = ioCmd[1];
			break;
                }

		case SET_SERIAL_RATE:
		{
			Serial.end();
			delay(500);
			Serial.begin(ioCmd[1]);
			break;
		}

		case GET_VERSION:{
			Serial.write(MAGIC_NUMBER);
			Serial.write(2); // size
			Serial.write(PUBLISH_VERSION);
			Serial.write((byte)MRLCOMM_VERSION);
			break;
			}

		case PULSE_IN: {
		    // might need to hack the pulseIn lib - but would
		    // like to do it without delay
			// http://arduino.cc/en/Tutorial/BlinkWithoutDelay
			int trigPin = ioCmd[1];
			int echoPin = ioCmd[2];
			// TODO - implement HI/LOW value & timeout & variable delay for trigger

			pinMode(trigPin, OUTPUT);
			pinMode(echoPin, INPUT);

			digitalWrite(trigPin, LOW);
			delayMicroseconds(2);

			digitalWrite(trigPin, HIGH);
			delayMicroseconds(10);

			digitalWrite(trigPin, LOW);
			unsigned long duration = pulseIn(echoPin, HIGH);

			//Calculate the distance (in cm) based on the speed of sound.
			// distance = duration/58.2;

			//sendMsg(4, ANALOG_VALUE, analogReadPin[i], readValue >> 8, readValue & 0xff);
 			//sendMsg(5, PULSE_IN, duration >> 24, duration >> 16, duration >> 8, duration & 0xff);
 			//sendMsg(6, SENSOR_DATA, 47, duration >> 24, duration >> 16, duration >> 8, duration & 0xff);

			Serial.write(MAGIC_NUMBER);
			Serial.write(5); // size 1 FN + 4 bytes of unsigned long
			Serial.write(PULSE_IN);
            // write the long value out
			Serial.write((byte)(duration >> 24));
			Serial.write((byte)(duration >> 16));
			Serial.write((byte)(duration >> 8));
			Serial.write((byte)duration & 0xff);

			break;
		}

		case SET_SAMPLE_RATE:{
			// 2 byte int - valid range 1-65,535
			sampleRate = (ioCmd[1]<<8) + ioCmd[2];
			if (sampleRate == 0)
				{ sampleRate = 1; } // avoid /0 error - FIXME - time estimate param
			break;
		}

		case SOFT_RESET:{
			softReset();
			break;
		}

		case STEPPER_ATTACH:{
			stepper_type& stepper = steppers[ioCmd[1]];
			stepper.index = ioCmd[1];
			stepper.type = ioCmd[2];
			stepper.currentPos = 0;
			stepper.targetPos = 0;
			stepper.speed = 100;

			if (stepper.type == STEPPER_TYPE_SIMPLE) {
				stepper.dirPin = ioCmd[3]; // dir pin
				stepper.stepPin = ioCmd[4]; // step pin
				pinMode(stepper.dirPin, OUTPUT);
				pinMode(stepper.stepPin, OUTPUT);
			} else {
				sendError(ERROR_UNKOWN_CMD);
			}
			break;
		}

		case STEPPER_RESET:{
			stepper_type& stepper = steppers[ioCmd[1]];
			stepper.currentPos = 0;
			stepper.targetPos = 0;
			stepper.speed = 100;
			break;
		}

		/* absolute position - not relative */
		case STEPPER_MOVE_TO:{
			stepper_type& stepper = steppers[ioCmd[1]];
			if (stepper.type == STEPPER_TYPE_SIMPLE) {
				stepper.targetPos = stepper.currentPos + (ioCmd[2]<<8) + ioCmd[3];
				// relative position & direction
				if (stepper.targetPos < 0) {
					// direction
					digitalWrite(stepper.dirPin, 1);
				} else {
					digitalWrite(stepper.dirPin, 0);
				}
			} else {
				sendError(ERROR_UNKOWN_CMD);
			}
			break;
		}

		case STEPPER_STOP:{
			stepper_type& stepper = steppers[ioCmd[1]];
			if (stepper.type == STEPPER_TYPE_SIMPLE) {
				stepper.targetPos = stepper.currentPos;
				sendStepperEvent(stepper, STEPPER_EVENT_STOP);
			} else {
				sendError(ERROR_UNKOWN_CMD);
			}
			break;
		}

			// --VENDOR CODE BEGIN--
			// --VENDOR CODE END--
// not sure if its worth implementing - same info can be retrieved from publish servo event & publish pin
/*

		case PINGDAR_ATTACH:{
			int pingdarIndex = ioCmd[1];
			pingdar_type& pingdar = pingdars[pingdarIndex];
			pingdar.servoIndex = ioCmd[2];
			pingdar.sensorIndex = ioCmd[3];
			pingdar.step = 1;
			break;
		}
*/
		// used by ultrasonic sensor
		case SENSOR_ATTACH:{
			int sensorIndex = ioCmd[1];
			sensor_type& sensor = sensors[sensorIndex];
			sensor.type = ioCmd[2];

			// initialize based on sensor type
			if (sensor.type == SENSOR_ULTRASONIC){
				sensor.trigPin = ioCmd[3];
				sensor.echoPin = ioCmd[4];
				pinMode(sensor.trigPin, OUTPUT);
				pinMode(sensor.echoPin, INPUT);
				//sensor.ping = new NewPing(sensor.trigPin, sensor.echoPin, 100);
			}

			break;
		}

		case SENSOR_POLLING_START:{
			int sensorIndex = ioCmd[1];
			sensor_type& sensor = sensors[sensorIndex];
			sensor.isRunning = true;

			// I'm used to ms - and would need to change some
			// interfaces if i was to support inbound longs
			//sensor.timeoutUS = ioCmd[2] * 1000;
			sensor.timeoutUS = 20000; // 20 ms
			sensor.state = ECHO_STATE_START;

			break;
		}

		case SENSOR_POLLING_STOP:{
			int sensorIndex = ioCmd[1];
			sensor_type& sensor = sensors[sensorIndex];
			sensor.isRunning = false;
			break;
		}

		case NOP:{
			// No Operation
			break;
		}

		default:{
		    sendError(ERROR_UNKOWN_CMD);
			break;
		}
		} // end switch

		// reset buffer
		memset(ioCmd,0,sizeof(ioCmd));
		byteCount = 0;

	} // if getCommand()

	// all reads are affected by sample rate
	if (loopCount%sampleRate == 0) {
		// digital polling read - send data for pins which are currently in INPUT mode only AND whose state has changed
		for (int i  = 0; i < digitalReadPollingPinCount; ++i)
		{
			if (debounceDelay)
			{
			  if (millis() - lastDebounceTime[digitalReadPin[i]] < debounceDelay)
			  {
			    continue;
			  }
			}

			// FIXME !! - normalize with analog
			// read the pin
			readValue = digitalRead(digitalReadPin[i]);

			// if my value is different from last time  && config - send it
			if (lastDigitalInputValue[digitalReadPin[i]] != readValue  || !digitalTriggerOnly)
			{
				Serial.write(MAGIC_NUMBER);
				Serial.write(4); // size
				Serial.write(PUBLISH_PIN);
				Serial.write(digitalReadPin[i]);// Pin#
				Serial.write(0); 	// MSB
				Serial.write(readValue); 	// LSB

			    lastDebounceTime[digitalReadPin[i]] = millis();
			}

			// set the last input value of this pin
			lastDigitalInputValue[digitalReadPin[i]] = readValue;
		}

		// analog polling read - send data for pins which are currently in INPUT mode only AND whose state has changed
		for (int i  = 0; i < analogReadPollingPinCount; ++i)
		{
			// read the pin
			readValue = analogRead(analogReadPin[i]);

			// if my value is different from last time - send it
			if (lastAnalogInputValue[analogReadPin[i]] != readValue   || !analogTriggerOnly) //TODO - SEND_DELTA_MIN_DIFF
			{
				//sendMsg(4, ANALOG_VALUE, analogReadPin[i], readValue >> 8, readValue & 0xff);

				Serial.write(MAGIC_NUMBER);
				Serial.write(4); //size
				Serial.write(PUBLISH_PIN);
				Serial.write(analogReadPin[i]);
				Serial.write(readValue >> 8);   // MSB
				Serial.write(readValue & 0xff);	// LSB

	        }
			// set the last input value of this pin
			lastAnalogInputValue[analogReadPin[i]] = readValue;
		}
	}

	// update moving servos - send events if required
	for (int i = 0; i < MAX_SERVOS; ++i)
	{
		servo_type& s = servos[i];
		if (s.isMoving && s.servo != 0){
			if (s.currentPos != s.targetPos)
			{
				// caclulate the appropriate modulus to drive
				// the servo to the next position
				// TODO - check for speed > 0 && speed < 100 - send ERROR back?
				int speedModulus = (100 - s.speed) * 10;
				if (loopCount % speedModulus == 0)
				{
					int increment = s.step * ((s.currentPos < s.targetPos)?1:-1);
					// move the servo an increment
					s.currentPos = s.currentPos + increment;
					s.servo->write(s.currentPos);
					if (s.eventsEnabled) sendServoEvent(s, SERVO_EVENT_POSITION_UPDATE);
				}
			} else {
				if (s.isSweeping) {
					if (s.targetPos == s.min){
						s.targetPos = s.max;
					} else {
						s.targetPos = s.min;
					}
				} else {
					if (s.eventsEnabled) sendServoEvent(s, SERVO_EVENT_STOPPED);
					s.isMoving = false;
				}
			}
		}
	}

	unsigned long ts;

	for (int i = 0; i < SENSORS_MAX; ++i) {
		sensor_type& sensor = sensors[i];
		if (sensor.isRunning == true){
			if (sensor.type == SENSOR_ULTRASONIC){

				// we are running & have an ultrasonic (ping) sensor
				// check to see what state we  are in

				if (sensor.state == ECHO_STATE_START){
					// trigPin prepare - start low for an
					// upcoming high pulse
					pinMode(sensor.trigPin, OUTPUT);
					digitalWrite(sensor.trigPin, LOW);

					// put the echopin into a high state
					// is this necessary ???
					pinMode(sensor.echoPin, OUTPUT);
					digitalWrite(sensor.echoPin, HIGH);

					ts = micros();
					if (ts - sensor.ts > 2){
						sensor.ts = ts;
						sensor.state = ECHO_STATE_TRIG_PULSE_BEGIN;
					}
				} else if (sensor.state == ECHO_STATE_TRIG_PULSE_BEGIN){

					// begin high pulse for at least 10 us
					pinMode(sensor.trigPin, OUTPUT);
					digitalWrite(sensor.trigPin, HIGH);

					ts = micros();
					if (ts - sensor.ts > 10){
						sensor.ts = ts;
						sensor.state = ECHO_STATE_TRIG_PULSE_END;
					}
				} else if (sensor.state == ECHO_STATE_TRIG_PULSE_END){
					// end of pulse
					pinMode(sensor.trigPin, OUTPUT);
					digitalWrite(sensor.trigPin, LOW);

					sensor.state = ECHO_STATE_MIN_PAUSE_PRE_LISTENING;
					sensor.ts = micros();
				} else if (sensor.state == ECHO_STATE_MIN_PAUSE_PRE_LISTENING){

					ts = micros();
					if (ts - sensor.ts > 1500){
						sensor.ts = ts;

						// putting echo pin into listen mode
						pinMode(sensor.echoPin, OUTPUT);
						digitalWrite(sensor.echoPin, HIGH);
						pinMode(sensor.echoPin, INPUT);

						sensor.state = ECHO_STATE_LISTENING;
					}

				} else if (sensor.state == ECHO_STATE_LISTENING) {
					// timeout or change states..
					int value = digitalRead(sensor.echoPin);
					ts = micros();

					if (value == LOW) {
						sensor.lastValue = ts - sensor.ts;
						sensor.ts = ts;
						sensor.state = ECHO_STATE_GOOD_RANGE;
					} else if (ts - sensor.ts > sensor.timeoutUS) {
						sensor.state = ECHO_STATE_TIMEOUT;
						sensor.ts = ts;
						sensor.lastValue = 0;
					}

				} else if (sensor.state == ECHO_STATE_GOOD_RANGE || sensor.state == ECHO_STATE_TIMEOUT) {
					Serial.write(MAGIC_NUMBER);
					Serial.write(6); // size 1 FN + 4 bytes of unsigned long
					Serial.write(PUBLISH_SENSOR_DATA);
					Serial.write(i);
		            // write the long value out
					Serial.write((byte)(sensor.lastValue >> 24));
					Serial.write((byte)(sensor.lastValue >> 16));
					Serial.write((byte)(sensor.lastValue >> 8));
					Serial.write((byte) sensor.lastValue & 0xff);
					sensor.state = ECHO_STATE_START;
				} // end else if

			} // if (sensor.type == SENSOR_ULTRASONIC)

		} // end isRunning

	} // end for each sensor

	// TODO - brake - speed - fractional stepping - other stepper types
	for (int i = 0; i < STEPPERS_MAX; ++i) {
		stepper_type& stepper = steppers[i];
		if (stepper.currentPos != stepper.targetPos){
			if (stepper.type == STEPPER_TYPE_SIMPLE){

				// direction is already set in initial STEPPER_MOVE

				if (stepper.currentPos < stepper.targetPos) {
					digitalWrite(stepper.stepPin, 1);
					delayMicroseconds(1); // :P should require another state? loop is ~106us min ?
					digitalWrite(stepper.stepPin, 0);
					stepper.currentPos++;
					sendStepperEvent(stepper, STEPPER_EVENT_STEP);

				} else if (stepper.currentPos > stepper.targetPos) {
					digitalWrite(stepper.stepPin, 1);
					delayMicroseconds(1); // :P should require another state? loop is ~106us min ?
					digitalWrite(stepper.stepPin, 0);
					stepper.currentPos--;
					sendStepperEvent(stepper, STEPPER_EVENT_STEP);
				}

				if (stepper.currentPos == stepper.targetPos){
					sendStepperEvent(stepper, STEPPER_EVENT_STOP);
				}

			}
		}
	}

	// FIXME - fix overflow with getDiff() method !!!
	unsigned long now = micros();
	loadTime = now - lastMicros; // avg outside
 	lastMicros = now;

	// report load time
	if (loadTimingEnabled && (loopCount%loadTimingModulus == 0)) {

 		// send it
		Serial.write(MAGIC_NUMBER);
		Serial.write(5); // size 1 FN + 4 bytes of unsigned long
		Serial.write(PUBLISH_LOAD_TIMING_EVENT);
        // write the long value out
		Serial.write((byte)(loadTime >> 24));
		Serial.write((byte)(loadTime >> 16));
		Serial.write((byte)(loadTime >> 8));
		Serial.write((byte) loadTime & 0xff);
	}

} // end of big loop

unsigned long getUltrasonicRange(sensor_type& sensor){

		// added for sensors which have single pin !
		pinMode(sensor.trigPin, OUTPUT);
		digitalWrite(sensor.trigPin, LOW);
		delayMicroseconds(2);

		digitalWrite(sensor.trigPin, HIGH);
		delayMicroseconds(10);

		digitalWrite(sensor.trigPin, LOW);

		// added for sensors which have single pin !
		pinMode(sensor.echoPin, INPUT);
		// CHECKING return pulseIn(sensor.echoPin, HIGH, sensor.timeoutUS);
		// TODO - adaptive timeout ? - start big - pull in until valid value - push out if range is coming close
		return pulseIn(sensor.echoPin, HIGH);
}

void sendServoEvent(servo_type& s, int eventType){
  	// check type of event - STOP vs CURRENT POS

	Serial.write(MAGIC_NUMBER);
	Serial.write(5); // size = 1 FN + 1 INDEX + 1 eventType + 1 curPos
	Serial.write(PUBLISH_SERVO_EVENT);
	Serial.write(s.index); // send my index
	// write the long value out
	Serial.write(eventType);
	Serial.write(s.currentPos);
	Serial.write(s.targetPos);
}

void sendStepperEvent(stepper_type& s, int eventType){
  	// check type of event - STOP vs CURRENT POS

	Serial.write(MAGIC_NUMBER);
	Serial.write(5); // size = 1 FN + 1 INDEX + 1 eventType + 1 curPos
	Serial.write(PUBLISH_STEPPER_EVENT);
	Serial.write(s.index); // send my index
	// write the long value out
	Serial.write(eventType);
	Serial.write(s.currentPos >> 8); // msb
	Serial.write(s.currentPos & 0xff); // lsb
}

void sendError(int type){
	Serial.write(MAGIC_NUMBER);
	Serial.write(2); // size = 1 FN + 1 TYPE
	Serial.write(PUBLISH_MRLCOMM_ERROR);
	Serial.write(type);
}

/* SEEMED LIKE A GOOD IDEA NOT !!!!
void sendMsg ( int num, ... )
{
	va_list arguments;
	// Initializing arguments to store all values after num
	va_start ( arguments, num );

	// write header
	msgBuf[0] = MAGIC_NUMBER;
	msgBuf[1] = num;

	// copies msg payload to buffer after header
	for ( int x = 2; x < num+2; x++ )
	{
		msgBuf[x] = (byte) va_arg ( arguments, int );
	}
	va_end ( arguments );                  // Cleans up the list
	Serial.write(msgBuf, num + 2);
	return;
}
*/

error: pathspec 'home/Alessandruino/MRLCommOculus4.ino' did not match any file(s) known to git


beautify

beautify

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/trinamic/T-Bone.git/'


Attiny TLC5940 signal generator code

Attiny TLC5940 signal generator code

/*
 * Chip AtTiny84A @ 8MHz - build via Arduino IDE
 *
 * Pins:
 *  2 - Blank Out
 *  3 - XLAT Out
 *  5 - GSCLK Out
 *  12 - Latch LED
 *  13 - XLAT IN (with external 10K pull up resistor)
 *
 * This code acts as a helper signal generator for using a TLC5940
 * "led" driver chip to run servos.  It generates the GSCLK pulse
 * and Blank and XLAT pulses.
 *
 * Data is clocked into the TLS5940 by another microcontroller, eg
 * in the case of the Hexaloop, a NodeMCU ESP8266 chip.
 *
 * The "other" microcontroller then sends the XLAT pulse to this ATTiny
 * which passes it on the the TLC5940 and fires the BLANK signal at the
 * right time.
 *
 * The GSCLK signal is started after the first XLAT pulse so that
 * the "other" microcontroller has chance to clock in an inital set
 * of servo positions.
 *
 * This code is heavily based on code found on the internet for
 * running LEDs on the TLC5940 from an ATTiny.  (hence a lot is commented)
 *
 * Note also that clocking in new servo positions too frequently causes
 * servo jitter, so you should update the servo positions no more than
 * every 25ms or so.
 *
 * Robert Longbottom, 2015
 */

#include <avr/io.h>
#include <avr/interrupt.h>

/*------------------------------------------------------------------------
 User configurable values
------------------------------------------------------------------------*/

//#ifndef NUM_TLC5940s
//#define NUM_TLC5940s 2
//#endif

/*------------------------------------------------------------------------
 Standard data types
------------------------------------------------------------------------*/
#include <stdint.h>
typedef uint8_t byte;
typedef int16_t int16;
typedef uint16_t uint16;

/*------------------------------------------------------------------------
 Servo settings
------------------------------------------------------------------------*/
/** The maximum angle of the servo. */
//#define SERVO_MAX_ANGLE     180
/** The 1ms pulse width for zero degrees (0 - 4095). */
//#define SERVO_MIN_WIDTH     140
/** The 2ms pulse width for 180 degrees (0 - 4095). */
//#define SERVO_MAX_WIDTH     490

/*------------------------------------------------------------------------
 Speed of timers
------------------------------------------------------------------------*/
// Timer 0 flips OC0A every (GSCLK_TIM+1) clock cycles
// With a setting of "1" we get a complete clock pulse every 4 CPU cycles
// ie. A 2mHz GSCLK at 8mHz CPU speed
//#define GSCLK_TIM 1
#define GSCLK_TIM 18 // RL, trial and error with an oscilloscope for servo control

// How many CPU cycles in a complete GSCLK pulse
#define GSCLK_CYCLES (2*(GSCLK_TIM+1))

/*------------------------------------------------------------------------
 Chip-specific things

 Most of the pin definitions can't be changed
------------------------------------------------------------------------*/

#if defined(__AVR_ATtiny84__)

// Pin definitions for ATtiny84
#define BLANK_PIN PB0
#define XLAT_PIN PB1
#define GSCLK_PIN PB2      /* Must be OC0A */
#define PIN_LED 1
//#define SERIAL_CLK PA4
//#define SERIAL_OUT PA5
//#define SERIAL_DDR DDRA    /* Where the serial direction bits are */
//#define SERIAL_PORT PORTA  /* Where the serial output pins are */

void initHardwareTimers()
{
 // Timer 0 -> 2MHz GSCLK output on OC0A
 TCCR0A=0; TCCR0B=0;   // Stop the timer
 TIMSK0 = 0;           // No interrupts from this timer
 TCNT0 = 0;            // Counter starts at 0
 OCR0A = GSCLK_TIM;    // Timer restart value
 TCCR0A = _BV(WGM01)   // CTC mode
         |_BV(COM0A0); // Toggle OC0A output on every timer restart
 TCCR0B = _BV(CS00);   // Start timer, no prescale

 // Timer 1 -> Generate an interrupt every 4096 GSCLK pulses
 TCCR1A=0; TCCR1B = 0; // Stop the timer
 TCNT1 = 0;            // Counter starts at 0
 OCR1A = 0;            // Where the interrupt happens during the count
 ICR1 = GSCLK_CYCLES*4; // There's four clock cycles for every CSCLK and 4096 per PWM cycle
 TIMSK1 = _BV(OCIE1A); // Interrupt every time the timer passes zero
 TCCR1A = 0;           // No outputs on chip pins
 TCCR1C = 0;           // Just in case...
 TCCR1B = _BV(WGM12)   // Start timer, CTC mode
         |_BV(WGM13)   // Start timer, CTC mode
         |_BV(CS12)    // div1024 prescale
         |_BV(CS10);   // div1024 prescale
}

#elif defined (__AVR_ATtiny85__)

// Pin definitions for ATtiny85
#define BLANK_PIN PB3
#define XLAT_PIN PB4
#define GSCLK_PIN PB0      /* Must be OC0A */
//#define SERIAL_CLK PB2
//#define SERIAL_OUT PB1
//#define SERIAL_DDR DDRB    /* Where the serial direction bits are */
//#define SERIAL_PORT PORTB  /* Where the serial output pins are */

void initHardwareTimers()
{
 // Timer 0 -> 2MHz GSCLK output on OC0A
 TCCR0A=0; TCCR0B=0;   // Stop the timer
 TIMSK = 0;            // No interrupts from this timer
 TCNT0 = 0;            // Counter starts at 0
 OCR0A = GSCLK_TIM;    // Timer restart value
 TCCR0A = _BV(WGM01)   // CTC mode
         |_BV(COM0A0); // Toggle OC0A output on every timer restart
 TCCR0B = _BV(CS00);   // Start timer, no prescale

 // Timer 1 -> Generate an interrupt every 4096 GSCLK pulses
 TCCR1=0;  GTCCR=0;    // Stop the timer
 TCNT1 = 0;            // Counter starts at 0
 OCR1A = 0;            // Where the interrupt happens during the count
 OCR1C = GSCLK_CYCLES; // Prescaler is 4096...total clocks is 4096*GSCLK_CYCLES
 TIMSK = _BV(OCIE1A);  // Interrupt every time the timer passes zero
 TCCR1 = _BV(CTC1)     // Start timer, CTC mode
         |_BV(CS10)    // Prescale=4096
         |_BV(CS12)
         |_BV(CS13);
}

#else
 unsupported_chip;
#endif

/*------------------------------------------------------------------------
 Interrupt handler - BLANK and XLAT are sent here
------------------------------------------------------------------------*/
// Set this flag whenever you want an XLAT bit to be sent
static bool doXLAT = false;

// Interrupt called at the end of each PWM cycle  - do BLANK/XLAT here
ISR(TIM1_COMPA_vect) // nb. *NOT*   "TIMER1_COMPA_vect"
{
 if (doXLAT) {
   PORTB |= _BV(BLANK_PIN)|_BV(XLAT_PIN);
   doXLAT = false;
   PINB = _BV(XLAT_PIN);      // XLAT low
 }
 else {
   PORTB |= _BV(BLANK_PIN);
 }
 PINB = _BV(BLANK_PIN);       // BLANK low
}

/*------------------------------------------------------------------------
 The TLC5940 controller
------------------------------------------------------------------------*/
class Tiny5940 {
/*
 typedef byte pwm_index_type;
 byte pwmData[24*NUM_TLC5940s];
 void sendByte(byte b) {
   // Put the byte in the USI data register
   USIDR = b;
   // Send it
#define tick USICR = _BV(USIWM0)|_BV(USITC)
#define tock USICR = _BV(USIWM0)|_BV(USITC)|_BV(USICLK);
   tick;  tock;  tick;  tock;
   tick;  tock;  tick;  tock;
   tick;  tock;  tick;  tock;
   tick;  tock;  tick;  tock;
 }
 */
public:
 void init() {
   cli();            // The system may already have interrupts running on the timers, disable them
   DDRB |= _BV(BLANK_PIN)|_BV(XLAT_PIN)|_BV(GSCLK_PIN);  // All port B pins as outputs
   PORTB |= _BV(BLANK_PIN);                              // BLANK pin high (stop the TLC5940, disable all output)
   initHardwareTimers();
   //setAll(0);
   PINB = _BV(XLAT_PIN);
   PINB = _BV(XLAT_PIN);
   //update();
   sei();
 }
 /*
 void setAll(uint16 value) {
   for (pwm_index_type i=0; i<16*NUM_TLC5940s; ++i) {
     set(i,value);
   }
 }
 void set(pwm_index_type channel, uint16 value) {
   if (channel < (16*NUM_TLC5940s)) {
     // Pointer to a pair of packed PWM values
     byte *pwmPair = pwmData+((channel>>1)*3);
     if (channel&1) {
       // Replace high part of pair
       pwmPair[1] = (pwmPair[1]&0x0f) | ((value<<4)&0xf0);
       pwmPair[2] = value >> 4;
     }
     else {
       // Replace low part of pair
       pwmPair[0] = value&0xff;
       pwmPair[1] = (pwmPair[1]&0xf0) | ((value>>8)&0x0f);
     }
   }
 }
*/
/** Converts and angle (0 - SERVO_MAX_ANGLE) to the inverted tlc channel value
    (4095 - 0). */
/*
uint16_t angleToVal(uint8_t angle)
{
    return 4095 - SERVO_MIN_WIDTH - (
            ((uint16_t)(angle) * (uint16_t)(SERVO_MAX_WIDTH - SERVO_MIN_WIDTH))
            / SERVO_MAX_ANGLE);
}
 */
 /** Sets a servo on channel to angle.
    \param channel which channel to set
    \param angle (0 - SERVO_MAX_ANGLE) */
    /*
void setServo(byte channel, uint8_t angle)
{
    set(channel, angleToVal(angle));
}

void setAllServo(uint8_t angle)
{
  setAll(angleToVal(angle));
}

 bool update() {
   // Still busy sending the previous values?
   if (doXLAT) {
     // Yes, return immediately
     return false;
   }

   // Set up USI to send the PWMdata
   byte sOut = _BV(SERIAL_CLK)|_BV(SERIAL_OUT);
   SERIAL_DDR |= sOut;     // Pins are outputs
   SERIAL_PORT &= ~sOut;   // Outputs start low
   USICR = _BV(USIWM0);    // Three wire mode

   // Send it...
   pwm_index_type numBytes = sizeof(pwmData);
   byte *pwm = pwmData+numBytes;   // High byte first...
   while (numBytes > 0) {
     sendByte(*--pwm);
     --numBytes;
   }

   // Tell the interrupt routine there's data to be latched
   doXLAT = true;

   return true;
 }
*/
};

// Create a Tiny5940 for people to use
Tiny5940 tlc;

volatile bool active = false;
volatile bool initialized = false;

ISR (PCINT0_vect)
{
  if ((PINA & (1 << PA0)) == 1)
  {
    // Low to high change
  }
  else
  {
    // High to low change
    // trigger XLAT to latch in current data (sent by another device)
    doXLAT = true;

    // activate timers to start sending pulses
    active = true;
  }
}

void setup() {

  // use PCINT0 to trigger XLAT and initial start
  DDRA &= ~(1 << PA0); // PA0 as input
  PORTA |= (1 << PORTA0); // Turn on pull up
  GIMSK |= (1 << PCIE0); // enable interrupts on PCINT0
  PCMSK0 = 0; // disable all PCINTS
  PCMSK0 |= (1 << PCINT0); // just enable interrupts on PCINT0 = PA0

  // Active Led
  pinMode(PIN_LED, OUTPUT);
  digitalWrite(PIN_LED, LOW);

  // Interrupts on
  sei();
}

void loop() {
  if (active) {
    if (!initialized) {
      tlc.init();
      initialized = true;
    }
    if (doXLAT) {
      digitalWrite(PIN_LED, HIGH);
    } else {
      digitalWrite(PIN_LED, LOW);
    }
  }
}

error: pathspec 'software/firmware/AtTinyTLC5940Hybrid/AtTinyTLC5940Hybrid.ino' did not match any file(s) known to git


Recongnize Skylander figures by NFC tag

Recongnize Skylander figures by NFC tag

#include <PN532.h>
#include <SPI.h>
#include <Adafruit_NeoPixel.h>

/*Chip select pin can be connected to D10 or D9 which is hareware optional*/
/*if you the version of NFC Shield from SeeedStudio is v2.0.*/
#define PN532_CS 10
PN532 nfc(PN532_CS);
#define PIN 6

enum Heros
{
   WashBuckler,
   BlastZone,
   Ninja,
   Unknown
} hero = Unknown;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, PIN, NEO_GRB + NEO_KHZ800);

void setup(void) {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'

  Serial.begin(57600);
  Serial.println("Hello!");
  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // Got ok data, print it out!
  Serial.print("Found chip PN5");
  Serial.println((versiondata>>24) & 0xFF, HEX);
  Serial.print("Firmware ver. ");
  Serial.print((versiondata>>16) & 0xFF, DEC);
  Serial.print('.');
  Serial.println((versiondata>>8) & 0xFF, DEC);
  Serial.print("Supports ");
  Serial.println(versiondata & 0xFF, HEX);
  // configure board to read RFID tags and cards
  nfc.SAMConfig();
}

void loop(void) {
  uint32_t id;
  // look for MiFare type cards
  id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);

  if (id != 0) {
    long color = 0;

    if (id == 3207720708 || id == 816892589)
    {
      hero = WashBuckler;
    }
    else if (id == 3562341356 || id == 2060644139)
    {
      hero = BlastZone;
    }
    else if (id == 3747222318)
    {
      hero = Ninja;
    }
    else
    {
      hero = Unknown;
    }

    switch (hero)
    {
      case WashBuckler:
        color = 0x00002020FFL; // blue
        Serial.println("Wash Buckler");
        break;
      case BlastZone:
        color = 0x00FF9900L; // orange
        Serial.println("Blast Zone");
        break;
       case Ninja:
        color = 0x0000FF00L; // green
        Serial.println("Ninja Stealth Elf");
        break;
      default:
        color = 0x00800000L; // dark red
        Serial.print("Unknown: ");
        Serial.println(id);
        break;
    }
    for (int i = 0; i < 24; i++)
    {
        strip.setPixelColor(i, color);
        strip.show();
        delay(25);
        strip.setPixelColor(i, 0x00000000L);
    }
    strip.show();
  }
}

error: pathspec 'uno/NfcReader/NfcReader.ino' did not match any file(s) known to git


put time comparison in separate function

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/cwilkens/helioscope-lamp.git/'


Demo clock untested code

Demo clock untested code

/*
  THIS SKETCH IMPLEMENTS IN THE loop() FUNCTION A CLOCK THAT DOES NOT ACCUMULATE MILLISECONDS BUT TRIES TO KEEP THEM WHITHIN TARGET MILLIS SPECIFICATION.
*/

#define CLOCK_PIN 13//Clock en pin 13

long frequencyInKHz = 5; // Shooting for 5 KHz
long initialMicros = 0;
long lastCutoffMicros = 0;
long nextCutoffMicros = 0;
long t_in_micros = 0;
long toggle_time_in_micros = 0;
int currentSignal = LOW;
int debugMode = 1;

void setup() {
  pinMode(CLOCK_PIN, OUTPUT);
  t_in_micros = (1/(frequencyInKHz * 1000)) * 1000000;
  toggle_time_in_micros = t_in_micros / 2;
  currentSignal = LOW;
  digitalWrite(CLOCK_PIN, currentSignal);
}

void loop() {
  jnck();
  // Depending on requested frequency, more stuff can be executed here while next toggle time is achieved.
  if (debugMode==1) Serial.println(micros());
}

void jnck()
{

  //INITIAL SETUP
  if(lastCutoffMicros == 0){
   lastCutoffMicros = micros();
   initialMicros = lastCutoffMicros; //Position in time when the clock started
   nextCutoffMicros = lastCutoffMicros + toggle_time_in_micros;
  }

  if(micros() > nextCutoffMicros){ //Cutoff!
    lastCutoffMicros = nextCutoffMicros; //Increase based on static target time that do not accumulate elapsed time
    nextCutoffMicros = nextCutoffMicros + toggle_time_in_micros;

    if (currentSignal == HIGH ) currentSignal = LOW;
    else currentSignal = HIGH; //TOGGLE CLOCK SIGNAL

    digitalWrite(CLOCK_PIN, currentSignal);
  }
}

error: pathspec 'demo_clock/demo_clock_autoadjusted/demo_clock_autoadjusted.ino' did not match any file(s) known to git


Ajout test servo

Ajout test servo

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
Servo myservo1;
Servo myservo2;
// twelve servo objects can be created on most boards

int pos = 180;
int LOW_POSITION =  180;
int HIGH_POSITION =  0;

void setup()
{
  Serial.begin(9600);
  myservo.attach(9);
  myservo.write(LOW_POSITION);
  myservo1.attach(8);
  myservo1.write(LOW_POSITION);
  myservo2.attach(7);
  myservo2.write(LOW_POSITION);

}

void loop()
{
    for (pos = 20; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      myservo1.write(pos);
      myservo2.write(pos);
      delay(40);                       // waits 15ms for the servo to reach the position
    }
    for (pos = 180; pos >= 20; pos -= 1) { // goes from 180 degrees to 0 degrees
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      myservo1.write(pos);
      myservo2.write(pos);
      delay(40);                       // waits 15ms for the servo to reach the position
    }
    myservo.write(LOW_POSITION);
    myservo1.write(LOW_POSITION);
    myservo2.write(LOW_POSITION);
    delay(120);

    /*for (pos = 180; pos >= 20; pos -= 1) { // goes from 180 degrees to 0 degrees
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(15);                       // waits 15ms for the servo to reach the position
    }
    delay(1000);
    for (pos = 20; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(20);                       // waits 15ms for the servo to reach the position
    }*/

  //}
}

error: pathspec 'arduino/TestServo/TestServo.ino' did not match any file(s) known to git


adding arduino sketch

adding arduino sketch

// License : BSD 3-Clause
// Version 0.0.1
// Author : Brendan Horan
//
// NOTES :
//   Install a 10uf capacitor between RESET and GND.
//   This prevents the Arduino Nano from restarting
//   on serial port open.

#include <IRremote.h>
IRsend irsend;

// Variable to hold incoming serial comms
int ctlmsg = 0;

void setup() {
        Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
        Serial.print ("Connected:9600");
}

void loop() {

        // wait for data
        if (Serial.available() > 0) {
                // read data
                ctlmsg = Serial.read();

                // send IR signal based on value from ir-blower server
               // 49 =1 , 50=2 etc
                switch (ctlmsg) {
                  case 49:
                    Serial.print("49");
                  //  irsend.send
                    break;
                  case 50:
                    Serial.print("50");
                 //   irsend.send
                    break;
                  case 51:
                    Serial.print("51");
                 //   irsend.send
                    break;
                  case 52:
                    Serial.print("52");
                 //   irsend.send
                    break;
                }

        }
}

error: pathspec 'arduino/ir_blower/ir_blower.ino' did not match any file(s) known to git


initial commit

initial commit

#include "application.h"
//#include "finite-state-machine.h"
#include "elapsedMillis.h"
#include "PietteTech_DHT.h"
#include "FiniteStateMachine.h"

#define APP_NAME "Thermostat"
// IO mapping
// D0 : relay: fan
// D1 : relay: heat
// D2 : relay: cold
// D3 : relay:
// D4 : DHT22
// D5 : unused
// D6 : unused
// D7 : unused
// A0~A7 : unused

//initialize states with proper enter, update and exit functions
State initState = State( initEnterFunction, initUpdateFunction, initExitFunction );
State idleState = State( idleEnterFunction, idleUpdateFunction, idleExitFunction );
State heatingState = State( heatingEnterFunction, heatingUpdateFunction, heatingExitFunction );
State endOfCycleState = State( endOfCycleEnterFunction, endOfCycleUpdateFunction, endOfCycleExitFunction );

//initialize state machine, start in state: Idle
FSM thermostatStateMachine = FSM(initState);

String VERSION = "Version 0.07";
int fan = D0;
int heat = D1;
int cold = D2;
int fanTesting;
int heatTesting;
int coldTesting;

// system defines
#define DHTTYPE  DHT22                // Sensor type DHT11/21/22/AM2301/AM2302
#define DHTPIN   4                    // Digital pin for communications
#define DHT_SAMPLE_INTERVAL   30000   // Sample room temperature every 30 seconds
void dht_wrapper(); // must be declared before the lib initialization
PietteTech_DHT DHT(DHTPIN, DHTTYPE, dht_wrapper);
bool bDHTstarted;       // flag to indicate we started acquisition
elapsedMillis dhtSampleInterval;

//milliseconds for the init cycle, so temperature samples get stabilized
//this should be in the order of the 5 minutes: 5*60*1000==300000
#define INIT_TIMEOUT 30000
elapsedMillis initTimer;

//milliseconds to leave the fan on when the target temp has been reached
//this evacuates the heat or the cold air from vents
#define END_OF_CYCLE_TIMEOUT 15000
elapsedMillis endOfCycleTimer;

//temperature related variables - internal
float targetTemp = 19.0;
float currentTemp = 20.0;
float currentHumidity = 0.0;
float margin = 0.5;
//temperature related variables - to be exposed in the cloud
String targetTempString = String(targetTemp); //String to store the target temp so it can be exposed and set
String currentTempString = String(currentTemp); //String to store the sensor's temp so it can be exposed
String currentHumidityString = String(currentHumidity); //String to store the sensor's humidity so it can be exposed

//testing variables
bool testing = false;

void setup() {

 //publish startup message with firmware version
 Particle.publish(APP_NAME, VERSION, 60, PRIVATE);

 //declare and init pins
 pinMode(fan, OUTPUT);
 pinMode(heat, OUTPUT);
 pinMode(cold, OUTPUT);
 myDigitalWrite(fan, LOW);
 myDigitalWrite(heat, LOW);
 myDigitalWrite(cold, LOW);

 //declare cloud variables
 //https://docs.particle.io/reference/firmware/photon/#particle-variable-
 //Currently, up to 10 cloud variables may be defined and each variable name is limited to a maximum of 12 characters
 if (Particle.variable("targetTemp", targetTempString)==false) {
   Particle.publish(APP_NAME, "ERROR: Failed to register variable targetTemp", 60, PRIVATE);
 }
 if (Particle.variable("currentTemp", currentTempString)==false) {
   Particle.publish(APP_NAME, "ERROR: Failed to register variable currentTemp", 60, PRIVATE);
 }
 if (Particle.variable("humidity", currentHumidityString)==false) {
   Particle.publish(APP_NAME, "ERROR: Failed to register variable humidity", 60, PRIVATE);
 }

 //declare cloud functions
 //https://docs.particle.io/reference/firmware/photon/#particle-function-
 //Currently the application supports the creation of up to 4 different cloud functions.
 //The length of the funcKey is limited to a max of 12 characters.
 // If you declare a function name longer than 12 characters the function will not be registered.
 //user functions
 if (Particle.function("setTargetTmp", setTargetTemp)==false) {
    Particle.publish(APP_NAME, "ERROR: Failed to register function setTargetTemp", 60, PRIVATE);
 }
 //testing functions
 if (Particle.function("setTesting", setTesting)==false) {
    Particle.publish(APP_NAME, "ERROR: Failed to register function setTesting", 60, PRIVATE);
 }
 if (Particle.function("setCurrTmp", setCurrentTemp)==false) {
    Particle.publish(APP_NAME, "ERROR: Failed to register function setCurrentTemp", 60, PRIVATE);
 }
 if (Particle.function("getOutputs", getOutputs)==false) {
    Particle.publish(APP_NAME, "ERROR: Failed to register function getOutputs", 60, PRIVATE);
 }

}

// This wrapper is in charge of calling the DHT sensor lib
void dht_wrapper() { DHT.isrCallback(); }

void loop() {
  readTemperature();
  thermostatStateMachine.update();
}

/*******************************************************************************
 * Function Name  : readTemperature
 * Description    : reads the temperature of the DHT22 sensor at every DHT_SAMPLE_INTERVAL
                    if testing the app, it returns right away
 * Return         : 0
 *******************************************************************************/
int readTemperature() {

  //are we testing the app? then no need to acquire from the sensor
  if (testing) {
   return 0;
  }

  //time is up? no, then come back later
  if (dhtSampleInterval < DHT_SAMPLE_INTERVAL) {
   return 0;
  }

  //time is up, reset timer
  dhtSampleInterval = 0;

  // start the sample
  if (!bDHTstarted) {
    DHT.acquire();
    bDHTstarted = true;
  }

  //still acquiring sample? go away
  if (DHT.acquiring()) {
    return 0;
  }

  //sample acquired - go ahead and store temperature and humidity in internal variables
  publishTemperature( (float)DHT.getCelsius(), (float)DHT.getHumidity() );

  //reset the sample flag so we can take another
  bDHTstarted = false;

  return 0;
}

/*******************************************************************************
 * Function Name  : publishTemperature
 * Description    : the temperature/humidity passed as parameters get stored in internal variables
                    and then published
 * Return         : 0
 *******************************************************************************/
int publishTemperature( float temperature, float humidity ) {

 char currentTempChar[32];
 currentTemp = temperature;
 int currentTempDecimals = (currentTemp - (int)currentTemp) * 100;
 sprintf(currentTempChar,"%0d.%d", (int)currentTemp, currentTempDecimals);

 char currentHumidityChar[32];
 currentHumidity = humidity;
 int currentHumidityDecimals = (currentHumidity - (int)currentHumidity) * 100;
 sprintf(currentHumidityChar,"%0d.%d", (int)currentHumidity, currentHumidityDecimals);

 //publish readings into exposed variables
 currentTempString = String(currentTempChar);
 currentHumidityString = String(currentHumidityChar);

 //publish readings
 Particle.publish(APP_NAME, "Current temperature: " + currentTempString, 60, PRIVATE);
 Particle.publish(APP_NAME, "Current humidity: " + currentHumidityString, 60, PRIVATE);

 return 0;

}

//utility functions
void initEnterFunction(){
 Particle.publish(APP_NAME, "initEnterFunction", 60, PRIVATE);
 //start the timer of this cycle
 initTimer = 0;

}
void initUpdateFunction(){
 //time is up?
 if (initTimer > INIT_TIMEOUT) {
  thermostatStateMachine.transitionTo(idleState);
 }
}
void initExitFunction(){
 Particle.publish(APP_NAME, "initExitFunction", 60, PRIVATE);
}

void idleEnterFunction(){
 Particle.publish(APP_NAME, "idleEnterFunction", 60, PRIVATE);
 myDigitalWrite(fan, LOW);
 myDigitalWrite(heat, LOW);
 myDigitalWrite(cold, LOW);
}
void idleUpdateFunction(){
 if ( currentTemp <= (targetTemp - margin) ) {
  Particle.publish(APP_NAME, "Starting to heat", 60, PRIVATE);
  thermostatStateMachine.transitionTo(heatingState);
 }
}
void idleExitFunction(){
 Particle.publish(APP_NAME, "idleExitFunction", 60, PRIVATE);
}

void heatingEnterFunction(){
 Particle.publish(APP_NAME, "heatingEnterFunction", 60, PRIVATE);
 myDigitalWrite(fan, HIGH);
 myDigitalWrite(heat, HIGH);
 myDigitalWrite(cold, LOW);
}
void heatingUpdateFunction(){
 if ( currentTemp >= (targetTemp + margin) ) {
  Particle.publish(APP_NAME, "Desired temperature reached", 60, PRIVATE);
  thermostatStateMachine.transitionTo(endOfCycleState);
 }
}
void heatingExitFunction(){
 Particle.publish(APP_NAME, "heatingExitFunction", 60, PRIVATE);
 myDigitalWrite(fan, HIGH);
 myDigitalWrite(heat, LOW);
 myDigitalWrite(cold, LOW);
}

void endOfCycleEnterFunction(){
 Particle.publish(APP_NAME, "endOfCycleEnterFunction", 60, PRIVATE);
 myDigitalWrite(fan, HIGH);
 myDigitalWrite(heat, LOW);
 myDigitalWrite(cold, LOW);

 //start the timer of this cycle
 endOfCycleTimer = 0;

}
void endOfCycleUpdateFunction(){
 //time is up?
 if (endOfCycleTimer > END_OF_CYCLE_TIMEOUT) {
  thermostatStateMachine.transitionTo(idleState);
 }
}
void endOfCycleExitFunction(){
 Particle.publish(APP_NAME, "endOfCycleExitFunction", 60, PRIVATE);
}

/*******************************************************************************
 * Function Name  : setTesting
 * Description    : sets the testing variable to true
 * Return         : 0
 *******************************************************************************/
int setTesting(String dummy)
{
  testing = true;
  return 0;
}

/*******************************************************************************
 * Function Name  : getOutputs
 * Description    : returns the outputs
 * Return         : returns the outputs
 *******************************************************************************/
int getOutputs(String dummy)
{
  // int fan = D0;
  // int heat = D1;
  // int cold = D2;
  return coldTesting*4 + heatTesting*2 + fanTesting*1;
}

/*******************************************************************************
 * Function Name  : setCurrentTemp
 * Description    : sets the current temperature of the thermostat
                    newCurrentTemp has to be a valid float value, or no new current temp will be set
 * Return         : 0, or -1 if it fails to convert the temp to float
 *******************************************************************************/
int setCurrentTemp(String newCurrentTemp)
{
  float tmpFloat = newCurrentTemp.toFloat();

  //update the current temp only in the case the conversion to float works
  // (toFloat returns 0 if there is a problem in the conversion)
  // sorry, if you wanted to set 0 as the current temp, you can't :)
  if ( tmpFloat > 0 ) {
    currentTemp = tmpFloat;
    currentTempString = String(currentTemp);
    Particle.publish(APP_NAME, "New current temp: " + currentTempString, 60, PRIVATE);
    return 0;
  } else {
    Particle.publish(APP_NAME, "ERROR: Failed to set new current temp to " + newCurrentTemp, 60, PRIVATE);
    return -1;
  }
}

/*******************************************************************************
 * Function Name  : setTargetTemp
 * Description    : sets the target temperature of the thermostat
                    newTargetTemp has to be a valid float value, or no new target temp will be set
 * Return         : 0, or -1 if it fails to convert the temp to float
 *******************************************************************************/
int setTargetTemp(String newTargetTemp)
{
  float tmpFloat = newTargetTemp.toFloat();
  //update the target temp only in the case the conversion to float works
  // (toFloat returns 0 if there is a problem in the conversion)
  // sorry, if you wanted to set 0 as the target temp, you can't :)
  if ( tmpFloat > 0 ) {
    targetTemp = tmpFloat;
    targetTempString = String(targetTemp);
    Particle.publish(APP_NAME, "New target temp: " + targetTempString, 60, PRIVATE);
    return 0;
  } else {
    Particle.publish(APP_NAME, "ERROR: Failed to set new target temp to " + newTargetTemp, 60, PRIVATE);
    return -1;
  }
}

void myDigitalWrite( int input, int status){
  digitalWrite(input, status);
  if (input == fan){
    fanTesting = status;
  }
  if (input == heat){
    heatTesting = status;
  }
  if (input == cold){
    coldTesting = status;
  }
}

error: pathspec 'minimalistthermostat.ino' did not match any file(s) known to git


debug fix, improved comments

debug fix, improved comments

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Duke-Medical-Instrumentation/Inception.git/'


Read write experiment: toggle big leds

Read write experiment: toggle big leds

Because not al boards have the smaller debug leds

error: pathspec 'experiments/SoftwareSerial/5' did not match any file(s) known to git
error: pathspec 'multi-read-write-precheck/PartA/PartA.ino' did not match any file(s) known to git


Comments, formatting

Comments, formatting

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/onordbo/mood-cloud.git/'


init class of a cart control

init class of a cart control

/*
Jhonatan da Silva
Last Updated version :
Sun Feb 12 20:23:38 2017
Number of code lines:
37
*/
class Carrinho{
    public:
        Carrinho();
        void begin();
        void f();
        void b();
        void l();
        void r();
    private:
        bool _status;
    };

    Carrinho::Carrinho(){

    }
    void Carrinho::begin(){
        Serial.begin(9600);
    }
    void Carrinho::f(){

    }
    void Carrinho::b(){

    }
    void Carrinho::l(){

    }
    void Carrinho::r(){

    }
Carrinho cart();
void setup(){

}
void loop(){

}

error: pathspec 'jtk/cart.ino' did not match any file(s) known to git


testing dra818

testing dra818

#include <SoftwareSerial.h>

SoftwareSerial radioSerial(10, 11); // RX, TX
#define TONE_PIN 8
char line[80];
int count = 0;

void setup() {
  pinMode(TONE_PIN, OUTPUT);

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // set the data rate for the SoftwareSerial port
  radioSerial.begin(9600);

  delay(1000);

  // check that radio works
  radioSerial.print("AT+DMOCONNECT\r\n");
  delay(1000);
  radioSerial.print("AT+DMOSETGROUP=0,145.6000,145.6000,0000,8,0000\r\n");

  Serial.println("Setup complete");

}

void loop() { // run over and over
  while (radioSerial.available()) {
    Serial.write(radioSerial.read());
  }
  while (Serial.available()) {
    line[count] = (char)Serial.read(); // store the char
    if (line[count++] == '\n'){        // if its a CR,
       line[count-1] = '\0';             //  zero-terminate it
       radioSerial.print(line);        //  and print it.
       radioSerial.print("\r\n"); // special format for DRA818
       Serial.print("Command sent: ");
       Serial.print("'");
       Serial.print(line);
       Serial.print("'");
       Serial.println("");
       count = 0;                      //  and reset the index.
    }
  }

  //play tone
  tone(TONE_PIN, 131, 1000); // Play C3 for 1s
  delay(1300);
  // stop the tone playing:
  noTone(TONE_PIN);
  tone(TONE_PIN, 1397, 1000); // Play F6 for 1s
  delay(1300);
  // stop the tone playing:
  noTone(TONE_PIN);
}

error: pathspec 'hacks/dra818_test/dra818_test.ino' did not match any file(s) known to git


functional prototype

functional prototype

#include <TimerOne.h>

#define LED_R         6
#define LED_G         9
#define LED_B        10
#define BUTTON        2
#define PUSHLOCK_NO   7
#define PUSHLOCK_NC   3

#define LOCKED      LOW
#define UNLOCKED   HIGH
#define UNDEFINED     2

byte button = 0;
byte pushlock = UNDEFINED;

int c_r = 0;
int c_g = 0;
int c_b = 0;
int fade_r = 5;
int fade_g = 15;
int fade_b = 10;
int fade_delay = 5;
int fdel = 1;
int cmode = 0;

int incomingByte = 0;
unsigned long tracker;

void setup() {
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(PUSHLOCK_NO, INPUT_PULLUP);
  pinMode(PUSHLOCK_NC, INPUT_PULLUP);

  pinMode(LED_R, OUTPUT);
  pinMode(LED_G, OUTPUT);
  pinMode(LED_B, OUTPUT);

  attachInterrupt(digitalPinToInterrupt(BUTTON), button_push, FALLING);
  attachInterrupt(digitalPinToInterrupt(PUSHLOCK_NO), pushlock_change, CHANGE);
  //attachInterrupt(digitalPinToInterrupt(PUSHLOCK_NC), pushlock_open, CHANGE);

  pushlock = digitalRead(PUSHLOCK_NO);
  tracker = millis();

  Serial.begin(115200);
}

void loop() {
  if (pushlock == LOCKED) {
    //Serial.println("LOCKED");
    if (heartbeat()) {

    }
  } else {
    //Serial.println("UNLOCKED");
    if (Serial.available() > 0) {
      incomingByte = Serial.read();
      Serial.println(incomingByte, HEX);
      Serial.println("HEARTBEAT");
      serial_flush();
      delay(1000);
    }
  }
  if (digitalRead(BUTTON)) {
  //if (button != 0) {
    button = 0;
    delay(100);
    cmode++;
  } else {
    Serial.println("Colormode");
    show_btn_color(cmode);
  }
  //button = 0;
}

void fade_btn(byte del) {
  analogWrite(LED_R, 255-c_r);
  analogWrite(LED_G, 255-c_g);
  analogWrite(LED_B, 255-c_b);

  //analogWrite(LED_G, 255);
  //analogWrite(LED_B, 255);

  c_r = c_r + fade_r;
  c_g = c_g + fade_g;
  c_b = c_b + fade_b;

  if ( c_r <= 0 || c_r >= 200 ) {
    fade_r = -fade_r;
  }
  if ( c_g <= 0 || c_g >= 255 ) {
    fade_g = -fade_g;
  }
  if ( c_b <= 0 || c_b >= 155 ) {
    fade_b = -fade_b;
  }

  fade_delay = fade_delay + fdel;
  if (fade_delay <= 1 || fade_delay >=del) {
    fdel = -fdel;
  }
  delay(fade_delay);
}

void show_btn_color( int mode ) {
  switch (mode) {
    case 1:
            fade_btn(10);

            break;
    case 2:
            fade_btn(5);
            break;
    case 3:
            analogWrite(LED_R, 0);
            analogWrite(LED_G, 255);
            analogWrite(LED_B, 0);

            break;
    case 4:
            analogWrite(LED_R, 0);
            analogWrite(LED_G, 0);
            analogWrite(LED_B, 255);

            break;
    case 5:
            analogWrite(LED_R, 0);
            analogWrite(LED_G, 255);
            analogWrite(LED_B, 255);

            break;
    case 6:
            analogWrite(LED_R, 255);
            analogWrite(LED_G, 255);
            analogWrite(LED_B, 0);

            break;
    case 7:
            fade_btn(1);
            break;
    case 8:
            c_r = 255;
            c_g = 0;
            fade_btn(10);
            break;
    default:
            cmode = 1;
            analogWrite(LED_R, 0);
            analogWrite(LED_G, 0);
            analogWrite(LED_B, 0);
            delay(50);
            analogWrite(LED_R, 200);
            analogWrite(LED_G, 200);
            analogWrite(LED_B, 200);
            delay(50);
            analogWrite(LED_R, 0);
            analogWrite(LED_G, 0);
            analogWrite(LED_B, 0);
            break;
  }
}

void button_push() {
  button = 1;
  //delay(50);
}

void pushlock_change() {
  pushlock = digitalRead(PUSHLOCK_NO);
}

void serial_flush() {
  int buf;
  while (Serial.available() > 0) {
      buf = Serial.read();
  }
}

int heartbeat() {
  int last_heartbeat;
  if (Serial.available() > 0) {
    incomingByte = Serial.read();

    serial_flush();

    if (incomingByte == 0x42) {
      last_heartbeat = millis()-tracker;
      tracker = millis();

      return last_heartbeat;
    } else {
      return -1;
    }
}