Skip to content

Commit

Permalink
Initial push od the Badge Contorl Arduino Driver
Browse files Browse the repository at this point in the history
  • Loading branch information
filipdulic committed Aug 17, 2016
1 parent 7ab7831 commit d7c3c5c
Show file tree
Hide file tree
Showing 8 changed files with 505 additions and 0 deletions.
96 changes: 96 additions & 0 deletions examples/BadgeControl/BadgeControl.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/**
* Badge Control
* Arduino code that give's the ESP8266 control over the board over
* serial interface. ESP can send comands to the LCD and play tones on
* the buzzer, the Arduino regualrly scans the joystick and buttons and
* send back satus messages.
*
* Protocol:
* The protocol is simple framing with CRC, that is somwhat customised
* to save buffer space. There are two types of incoming messages from
* the ESP, control messages, and LCD frame buffer messages, they are
* diferentiated by different Start Bytes STX and LCDSTX, and a
* single type of outgoing status messages, all are framed as folows.
*
* [Start byte][Escaped[Data Array]][End Byte]
*
* If the Data Array has any bytes that are either the Start Byte,
* End Byte, or the Escape Byte, the byte is presceded by the Escape
* Byte. Example:
* [Data] = [D1][D2][D3][D4 = Start Byte][D5].
* [Escaped[Data]] = [D1][D2][D3][Escape Byte][D4 = Start Byte][D5]
*
* Control Messages ESP->Arduino
* [Data] <= [ID][CMD][CMD Data][CRC]
* [Tone MSG] <= [ID][Tone CMD][FreqH][FreqL][DurH][DurL][CRC]
* [LCD Control] <= [ID][LCDC CMD][Control Byte][CRC]
* ID = Message ID
* CMD = What command the message refers to. (Tone and LCD control msg)
* CRC = Single byte CRC of the ID,CMD, and CMD Data, byte array.
* FreqH/L = High and low byte od the frequency 16bit integer
* DurH/L = High and low byte of the duration 16bit integer
* Control Byte = Byte to be sent to the LCD as a control byte.
*
* LCD Frame Buffer Messages ESP->Arduino
* [Data] <= [LCD Frame Buffer]
* This type of message doen't use ID CMD or the CRC bytes, all bytes
* between the Start and End Bytes are sent to the LCD as Data bytes.
* Maximum 504 bytes of frame buffer is possible.
*
* Status Messages
* [Data] <= [JXH][JXL][JYH][JYL][JB][B1][B2][EN]<[ID][ACK]>[CRC]
* JXH/L = Joystick X axis 16bit status
* JYH/L = Joystick Y axis 16bit status
* JB = Joystick Button status
* B1 = Button 1 status
* B2 = Button 2 status
* EN = Receved message enable, if a message was receved this is set to
* 1 if the message was a control message, and 2 if it was a frame
* ID = ID of the message that was receved, only sent if EN is set
* ACK = 1 if message was receved corectly, 0 otherwise. only sent EN==1
* @author Filip Dulic
* @version 1.0 18/8/2016
*/

#include <Arduino.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include "Messanger.h"
#include "LCD.h"
#include "StatusMsg.h"
#include "common.h"


SoftwareSerial sSerial(7, 6); //RX,TX

void setup() {
sSerial.begin(9600);
LCD.begin();
}

void loop() {
while (sSerial.available()) {
byte read = sSerial.read();
if (Messanger.receveByte(read) == true) break;
}

if (Messanger.MessageReceved() == true) {
if (Messanger.handleMessage() == true) {
Status.setReturnMsgACK(1); //ACK
} else {
Status.setReturnMsgACK(0); //NOACK
}
Status.setReturnMsgEN(1);
Status.setReturnMsgID(Messanger.getMessageID());
}

if(LCD.BufferReceved() == true) {
LCD.sendBuffer();
Status.setReturnMsgEN(2); //EN 2 fro LCD buffer
Status.setReturnMsgID(0); //ID=0
Status.setReturnMsgACK(1); //ACK
LCD.clearBuffer();
}

//Status.send();
}
76 changes: 76 additions & 0 deletions examples/BadgeControl/LCD.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "LCD.h"

LCDClass LCD;

#include <Arduino.h>

/* Pin definitions:
Most of these pins can be moved to any digital or analog pin.
DN(MOSI)and SCLK should be left where they are (SPI pins). The
LED (backlight) pin should remain on a PWM-capable pin. */
const int scePin = 8; // SCE
const int rstPin = 9; // RST
const int dcPin = 10; // DC.
const int sdinPin = 11; // DN
const int sclkPin = 13; // SCLK

/* PCD8544-specific defines: */
#define LCD_COMMAND 0
#define LCD_DATA 1

/* 84x48 LCD Defines: */
#define LCD_WIDTH 84 // Note: x-coordinates go wide
#define LCD_HEIGHT 48 // Note: y-coordinates go high
#define WHITE 0 // For drawing pixels. A 0 draws white.
#define BLACK 1 // A 1 draws black.

void LCDClass::sendCommand(byte command) {
//Tell the LCD that we are writing either to data or a command
digitalWrite(dcPin, LCD_COMMAND);
//Send the data
digitalWrite(scePin, LOW);
SPI.transfer(command); //shiftOut(sdinPin, sclkPin, MSBFIRST, data);
digitalWrite(scePin, HIGH);
}

void LCDClass::sendBuffer() {
//Tell the LCD that we are writing either to data or a command
digitalWrite(dcPin, LCD_DATA);

//Send the data
digitalWrite(scePin, LOW);
SPI.transfer(buffer,index);
digitalWrite(scePin, HIGH);
}

void LCDClass::reset() {
digitalWrite(rstPin, LOW);
digitalWrite(rstPin, HIGH);
}

//This sends the magical commands to the PCD8544
void LCDClass::begin() {
//Configure control pins
pinMode(scePin, OUTPUT);
pinMode(rstPin, OUTPUT);
pinMode(dcPin, OUTPUT);
pinMode(sdinPin, OUTPUT);
pinMode(sclkPin, OUTPUT);

SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV2);
SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(MSBFIRST);

//Reset the LCD to a known state
reset();

sendCommand(0x21); //Tell LCD extended commands follow
sendCommand(0xA0); //Set LCD Vop (Contrast)
sendCommand(0x04); //Set Temp coefficent
sendCommand(0x16); //LCD bias mode 1:48 (try 0x13)
//We must send 0x20 before modifying the display control mode
sendCommand(0x20);
sendCommand(0x0C); //Set display control, normal mode.
}

27 changes: 27 additions & 0 deletions examples/BadgeControl/LCD.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef _LCD_H_INCLUDED
#define _LCD_H_INCLUDED

#include <Arduino.h>
#include <SPI.h>

class LCDClass{
public:
LCDClass(){index = 0;receved = false;}
void begin();
void sendCommand(byte command);
void sendBuffer();
void reset();
void pause(){SPI.end();}
void unPause(){SPI.begin();}
void addToBuffer(byte data){if(index < 504)buffer[index++] = data;}
void clearBuffer(){index=0;receved = false;}
void setRecevedBuffer(){receved = true;}
bool BufferReceved(){return receved;}
private:
byte buffer[504];
int index;
bool receved;
};

extern LCDClass LCD;
#endif
128 changes: 128 additions & 0 deletions examples/BadgeControl/Messanger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#include "Messanger.h"
#include "common.h"


MessangerClass Messanger;

MessangerClass::MessangerClass() {
startByte = NOSTART;
rxBufferIndex=0;
msgReceved=false;
bufferOverflow=false;
}

bool MessangerClass::checkCRC() {
byte CRC = 0;
byte ID = msgRecevedBuffer[0];
byte Len;
if (ID == LCDC) Len = 3;
if (ID == TONE) Len = 6;

for (int i = 0;i<Len;i++) {
CRC += msgRecevedBuffer[i];
}
return CRC == msgRecevedBuffer[Len];
}

bool MessangerClass::checkEscape() {
if (escNext == false) {
if (read == ESC) {
escNext = true;
return true;
}
} else {
escaped = true;
escNext = false;
}
return false;
}

bool MessangerClass::handleStartByte() {
if (read == STX || read == LCDSTX) {
startByte = read;
if (startByte == STX) {
rxBufferIndex = 0;
bufferOverflow = false;
}
if (startByte == LCDSTX) {
LCD.clearBuffer();
}
return true;
}
return false;
}

bool MessangerClass::handleEndByte() {
if (read == ETX) {
if (startByte == STX) {
for (byte i = 0; i < rxBufferIndex; i++)
msgRecevedBuffer[i] = rxBuffer[i];
rxBufferIndex = 0;
bufferOverflow = false;
msgReceved = true;
ID = msgRecevedBuffer[0];
CMD = msgRecevedBuffer[1];
}
if (startByte == LCDSTX){
LCD.setRecevedBuffer();
}
startByte = NOSTART;
return true;
}
return false;
}

bool MessangerClass::receveByte(byte bRead) {
escaped = false;
read = bRead;
if (checkEscape() == true) return false;
if (escaped == false) {
if (handleStartByte() == true) return false;
if (handleEndByte() == true) return true;
}
if (startByte == LCDSTX) {
LCD.addToBuffer(read);
return false;
}
if (startByte == STX) {
rxBuffer[rxBufferIndex++] = read;
}
if (rxBufferIndex == RX_BUFFER_MAX){
//fuckup buffer overload
rxBufferIndex = 0;
startByte = NOSTART;
bufferOverflow = true;
return true;
}
return false;
}

bool MessangerClass::handleMessage() {
msgReceved = false;
switch (CMD)
{
case LCDC:
if (checkCRC() == true) {
//send LCD ctl..
if (msgRecevedBuffer[2] == 0)
LCD.reset();
else
LCD.sendCommand(msgRecevedBuffer[2]);
return true;
} else return false;
break;
case TONE:
if (checkCRC() == true) {
int freq = (msgRecevedBuffer[2] << 8 | msgRecevedBuffer[3]);
int dur = (msgRecevedBuffer[4] << 8 | msgRecevedBuffer[5]);
LCD.pause();
tone(12,freq,dur);
delay(dur);
LCD.unPause();
return true;
} else return false;
break;
default:
return false;
}
}
48 changes: 48 additions & 0 deletions examples/BadgeControl/Messanger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef _MESSANGER_H_INCLUDED
#define _MESSANGER_H_INCLUDED

#include "LCD.h"

#define NOSTART 0
#define TONE 1
#define LCDC 2

#define STX 1
#define ETX 2
#define ESC 3
#define LCDSTX 4

#define RX_BUFFER_MAX 16

class MessangerClass {
public:
MessangerClass();

bool receveByte(byte read);
bool checkCRC();
bool MessageReceved() {return msgReceved;}
byte getMessageID() {return ID;}
byte getMessageCMD() {return CMD;}
byte *getMessage() {return msgRecevedBuffer;}
bool handleMessage();
private:
bool checkEscape();
bool handleStartByte();
bool handleEndByte();
byte read;
byte startByte;
byte rxBuffer[RX_BUFFER_MAX];
byte rxBufferIndex;
byte msgRecevedBuffer[RX_BUFFER_MAX];
bool msgReceved;
bool bufferOverflow;
bool escaped;
bool escNext;
byte ID;
byte CMD;

};

extern MessangerClass Messanger;
#endif

Loading

0 comments on commit d7c3c5c

Please sign in to comment.