Include Include Include Include
Include Include Include Include
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <aREST.h>
#include <Servo.h>
if(WiFi.status() == WL_CONNECTED){
wifiConnected = 1;
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP ");
Serial.println(WiFi.localIP());
delay(500);
} else {
// Make sure WiFi is disconnected
WiFi.disconnect();
delay(50);
wifiConnected = 0;
Serial.println("");
Serial.println("*** WiFi NOT connected ***");
}
char* out_topic = rest.get_topic();
if(enableCloud == 1){
Serial.println("Enabled");
}else{
WiFi.softAPdisconnect(true);
delay(50);
if(enableAP == 0){
Serial.println("AP Mode disabled");
}
// Init variables and expose them to REST API
restAP.variable("build",&build);
restAP.variable("analogValues",&analogValues);
restAP.variable("digitalValues",&digitalValues);
// Function to be exposed
restAP.function("calibrate",calibrate);
restAP.function("commands",commands);
restAP.function("logo",logo);
restAP.function("runCommands",runCommands);
restAP.function("attachServos",attachServos);
restAP.function("setMotorDriver",setMotorDriver);
restAP.function("readPins",readPins);
restAP.set_id("local");
restAP.set_name(deviceName);
if(enableAP == 1){
WiFi.softAP(ssidAP, passwordAP);
Serial.println("");
Serial.println("WiFi AP: Access Point created");
Serial.print("SSID AP: ");
Serial.println(ssidAP);
Serial.print("Password: ");
Serial.println(passwordAP);
Serial.println("");
server.begin();
Serial.println("");
Serial.println("-----------------------------");
Serial.println("Web Server");
Serial.println("-----------------------------");
Serial.println("Started");
delay(500);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillisWiFi >= intervalWiFi) {
// save the last time you checked
previousMillisWiFi = currentMillis;
if(wifiConnected == 1){
if(WiFi.status() != WL_CONNECTED){
WiFi.disconnect();
delay(50);
wifiConnected = 0;
}
}
}
runLogo();
runCommands("");
if(enableCloud == 1){
if(!clientAP.available()){
Serial.print("NOT clientAP.available() ,");
runLogo();
runCommands("");
delay(1);
}else{
restAP.handle(clientAP);
}
}
// Handles message arrived on subscribed topic(s)
void callback(char* topic, byte* payload, unsigned int length) {
rest.handle_callback(client, topic, payload, length);
}
String getValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = {
0, -1 };
int maxIndex = data.length()-1;
for(int i=0; i<=maxIndex && found<=index; i++){
if(data.charAt(i)==separator || i==maxIndex){
found++;
strIndex[0] = strIndex[1]+1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
String rVal = "";
if(found>index){
rVal = data.substring(strIndex[0], strIndex[1]);
rVal.replace(" ","");
}
return rVal;
}
// Custom function accessible by the API
int readPins(String command) {
Serial.print("rP ");
bool readAll = false;
if(command == "")
readAll = true;
String str_Command;
int item_counter = 0;
while(1){
str_Command = getValue(command, ',', item_counter++);
if(!readAll && str_Command == "")
break;
if(readAll || str_Command == "A0"){
PinA0 = analogRead(A0);
delay(wait);
}
if(readAll || str_Command == "D0"){
PinD0 = digitalRead(gpio[0]);
delay(wait);
}
if(readAll || str_Command == "D1"){
PinD1 = digitalRead(gpio[1]);
delay(wait);
}
if(readAll || str_Command == "D2"){
PinD2 = digitalRead(gpio[2]);
delay(wait);
}
if(readAll || str_Command == "D3"){
PinD3 = digitalRead(gpio[3]);
delay(wait);
}
if(readAll || str_Command == "D4"){
PinD4 = digitalRead(gpio[4]);
delay(wait);
}
if(readAll || str_Command == "D5"){
PinD5 = digitalRead(gpio[5]);
delay(wait);
}
if(readAll || str_Command == "D6"){
PinD6 = digitalRead(gpio[6]);
delay(wait);
}
if(readAll || str_Command == "D7"){
PinD7 = digitalRead(gpio[7]);
delay(wait);
}
if(readAll || str_Command == "D8"){
PinD8 = digitalRead(gpio[8]);
delay(wait);
}
break;
}
analogValues = String(PinA0);
digitalValues = String(PinD0) + "," + String(PinD1) + "," + String(PinD2) + "," +
String(PinD3) + "," + String(PinD4) + "," + String(PinD5) + "," + String(PinD6) +
"," + String(PinD7) + "," + String(PinD8);
return 1;
}
int commands(String command) {
String str_Command;
int item_counter = 0;
while(1){
str_Command = getValue(command, ':', item_counter++);
if(str_Command == "")
break;
addCommandToQueue(str_Command);
}
return item_counter;
}
void addCommandToQueue(String command){
String data;
int formatInt;
int pinInt;
int valueInt;
String value = "";
int durationInt;
int item_counter = 0;
while(1){
data = getValue(command, ',', item_counter++);
if(data == "")
break;
formatInt = data.toInt();
commandQueue[pinInt][commandIndex][0] = formatInt;
commandQueue[pinInt][commandIndex][1] = valueInt;
commandQueue[pinInt][commandIndex][2] = durationInt;
break;
}
}
int runLogo(){
unsigned long currentMillis = millis();
if(currentLogoCommand[0] >= 0 && currentLogoCommandExpiry > currentMillis)
return 1;
else {
if(logoQueueIndex > 0){
// save the new command details
int new_command = logoQueue[0][0];
int new_value = logoQueue[0][1];
for(int pos=0;pos<(logoQueueIndex-1);pos++){
logoQueue[pos][0] = logoQueue[(pos+1)][0];
logoQueue[pos][1] = logoQueue[(pos+1)][1];
}
// make sure the last one is removed (set to -1)
logoQueue[(logoQueueIndex-1)][0] = -1;
logoQueue[(logoQueueIndex-1)][1] = -1;
logoQueueIndex--;
executeLogo(new_command,new_value);
} else{
if(currentLogoCommandExpiry == 0)
return 1;
else if(currentLogoCommand[0] == 0)
return 1; // current command is STOP, so don't re-execute
else{
// else stop the command
executeLogo(0);
}
}
}
int executeLogo(int command){
return executeLogo(command,0);
}
int executeLogo(int command, int value){
int duration = getLogoDuration(command,value);
unsigned long currentMillis = millis();
currentLogoCommand[0] = command;
currentLogoCommand[1] = value;
currentLogoCommandExpiry = (currentMillis + (long)duration);
// Special case for indefinite commands
if(value == 0)
currentLogoCommandExpiry = 0;
if(motorPinsConfigured == 0){
initialiseMotorPins();
pinMode(gpio[pinPen], OUTPUT);
digitalWrite(gpio[pinPen],1); // Put the pen down by default.
}
if(command == 0){
motorLeftST();
motorRightST();
}
if(command == 1){
motorLeftFD();
motorRightFD();
}
if(command == 2){
motorLeftBK();
motorRightBK();
}
if(command == 3){
motorLeftBK();
motorRightFD();
}
if(command == 4){
motorLeftFD();
motorRightBK();
}
if(command == 5){
motorLeftST();
motorRightFD();
}
if(command == 6){
motorRightST();
motorLeftFD();
}
if(command == 7){
motorLeftST();
motorRightBK();
}
if(command == 8){
motorRightST();
motorLeftBK();
}
if(command == 9){
// Pen Up. Default behaviour turns the pinPen on and off
digitalWrite(gpio[pinPen],0);
}
// 10. PD (or PENDOWN) - Put the Pen down
if(command == 10){
// Pen Down. Default behaviour turns the pinPen on and off. Other Option to move
servo
digitalWrite(gpio[pinPen],1);
}
return 1;
}
void motorLeftST(){
if(motorDriver == 1){
analogWrite(gpio[pinA1A],0);
analogWrite(gpio[pinA1B],0);
digitalWrite(gpio[pinA1A],0);
digitalWrite(gpio[pinA1B],0);
} else {
analogWrite(gpio[pinA1A],0);
digitalWrite(gpio[pinB1A],0);
}
}
void motorRightST(){
if(motorDriver == 1){
analogWrite(gpio[pinB1A],0);
analogWrite(gpio[pinB1B],0);
digitalWrite(gpio[pinB1A],0);
digitalWrite(gpio[pinB1B],0);
} else if(motorDriver == 2){
} else {
analogWrite(gpio[pinA1B],0);
digitalWrite(gpio[pinB1B],0);
}
}
void motorLeftFD(){
if(motorDriver == 1){
digitalWrite(gpio[pinA1A],1);
analogWrite(gpio[pinA1B],(maxPWM - leftPWMF));
} else if(motorDriver == 2){
} else {
analogWrite(gpio[pinA1A],leftPWMF);
digitalWrite(gpio[pinB1A],1);
}
}
void motorRightFD(){
if(motorDriver == 1){
digitalWrite(gpio[pinB1A],1);
analogWrite(gpio[pinB1B],(maxPWM - rightPWMF));
} else if(motorDriver == 2){
} else {
analogWrite(gpio[pinA1B],rightPWMF);
digitalWrite(gpio[pinB1B],1);
}
}
void motorLeftBK(){
if(motorDriver == 1){
digitalWrite(gpio[pinA1A],0);
analogWrite(gpio[pinA1B],leftPWMB);
} else if(motorDriver == 2){
} else {
analogWrite(gpio[pinA1A],leftPWMF);
digitalWrite(gpio[pinB1A],0);
}
}
void motorRightBK(){
if(motorDriver == 1){
digitalWrite(gpio[pinB1A],0);
analogWrite(gpio[pinB1B],rightPWMB);
} else if(motorDriver == 2){
} else {
analogWrite(gpio[pinA1B],rightPWMF);
digitalWrite(gpio[pinB1B],0);
}
}
void initialiseMotorPins(){
pinMode(gpio[pinA1A], OUTPUT);
pinMode(gpio[pinA1B], OUTPUT);
pinMode(gpio[pinB1A], OUTPUT);
pinMode(gpio[pinB1B], OUTPUT);
motorPinsConfigured = 1;
}
int getLogoDuration(int command, int value){
if(value == 0)
return 0;
if(command == 0)
return value;
if(command == 1)
return (int)(1000.0*(float)value/(float)speedFD);
if(command == 2)
return (int)(1000.0*(float)value/(float)speedBK);
if(command == 3)
return (int)(1000.0*(float)value/(float)speedLT);
if(command == 4)
return (int)(1000.0*(float)value/(float)speedRT);
if(command == 5)
return (int)(1000.0*(float)value/(float)speedARCFL);
if(command == 6)
return (int)(1000.0*(float)value/(float)speedARCFR);
if(command == 7)
return (int)(1000.0*(float)value/(float)speedARCBL);
if(command == 8)
return (int)(1000.0*(float)value/(float)speedARCBR);
return 0;
}
int calibrate(String command){
String str_Pair;
String str_Constant;
String str_Value;
int item_counter = 0;
while(1){
// Get the next Pair from the command string
str_Pair = getValue(command, ';', item_counter++);
if(str_Pair == "")
break;
updateConstant(str_Constant,iValue);
break;
}
}
return item_counter;
}
int updateConstant(String c, int value){
// Update the 'constant' c setting it to value
if(c == "leftPWMF")
leftPWMF = value;
if(c == "rightPWMF")
rightPWMF = value;
if(c == "leftPWMB")
leftPWMB = value;
if(c == "rightPWMB")
rightPWMB = value;
if(c == "speedFD")
speedFD = value;
if(c == "speedBK")
speedBK = value;
if(c == "speedLT")
speedLT = value;
if(c == "speedRT")
speedRT = value;
if(c == "speedARCFL")
speedARCFL = value;
if(c == "speedARCFR")
speedARCFR = value;
if(c == "speedARCBL")
speedARCBL = value;
if(c == "speedARCBL")
speedARCBL = value;
if(c == "speedARCBR")
speedARCBR = value;
return 1;
}
int runCommands(String command){
for(int pinInt=0;pinInt<maxPinsIndex;pinInt++){
int nextCommandIndex = commandQueueIndex[pinInt];
if(nextCommandIndex>0){
if(format == 0){
// Analog
pinMode(gpio[pinInt], OUTPUT);
// special case if the pin has a servo attached
if(servoArray[0] == pinInt && servo1.attached())
servo1.write(value);
else if(servoArray[1] == pinInt && servo2.attached())
servo2.write(value);
else if(servoArray[2] == pinInt && servo3.attached())
servo3.write(value);
else if(servoArray[3] == pinInt && servo4.attached())
servo4.write(value);
else
analogWrite(gpio[pinInt],value);
pinMode(gpio[pinInt], OUTPUT);
digitalWrite(gpio[pinInt],value);
neoPixelRoutine(format,pinInt,value);
}
}
}
return 1;
}
int attachServos(String command){
String str_Command;
int item_counter = 0;
int item_counter2 = 0;
String data;
int servoNumber = 0;
int pinInt;
while(1){
str_Command = getValue(command, ':', item_counter++);
if(str_Command == "")
break;
while(1){
data = getValue(command, ',', item_counter2++);
if(data == "")
break;
servoNumber = data.toInt();
if(servoNumber == 1){
if(servo1.attached())servo1.detach();
servo1.attach(gpio[pinInt]);
servoArray[0] = pinInt;
}
if(servoNumber == 2){
if(servo2.attached())servo2.detach();
servo2.attach(gpio[pinInt]);
servoArray[1] = pinInt;
}
if(servoNumber == 3){
if(servo3.attached())servo3.detach();
servo3.attach(gpio[pinInt]);
servoArray[2] = pinInt;
}
if(servoNumber == 4){
if(servo4.attached())servo4.detach();
servo4.attach(gpio[pinInt]);
servoArray[3] = pinInt;
}
}
}
return item_counter;
}
int attachNeoPixel(String command){
return 1;
}
int setMotorDriver(String command){
int type = command.toInt();
if(type >= 0 && type <= 2){
motorDriver = type;
return motorDriver;
}
return -1;
}
// Custom function accessible by the API
int logo(String command) {
int item_counter = 0;
while(1){
// Get the next command,value from the command string
str_CommandValue = getValue(command, ';', item_counter++);
if(str_CommandValue == "")
break;
addLogoToQueue(str_Command,iValue);
break;
}
return item_counter;
}
int addLogoToQueue(String command, int value){
if(logoQueueIndex > maxLogoQueueIndex)
return 0;
command.toUpperCase();
int int_command;
if(command == "ST" || command == "STOP")
int_command = 0;
else if(command == "FD" || command == "FORWARD")
int_command = 1;
else if(command == "BK" || command == "BACK")
int_command = 2;
else if(command == "LT" || command == "LEFT")
int_command = 3;
else if(command == "RT" || command == "RIGHT")
int_command = 4;
else if(command == "ARCFL")
int_command = 5;
else if(command == "ARCFR")
int_command = 6;
else if(command == "ARCBL")
int_command = 7;
else if(command == "ARCBR")
int_command = 8;
else if(command == "PU" || command == "PENUP")
int_command = 9;
else if(command == "PD" || command == "PENDOWN")
int_command = 10;
else
return 0; // command not supported
logoQueue[logoQueueIndex][0] = int_command;
logoQueue[logoQueueIndex][1] = value;
logoQueueIndex++;
return 1;
}
void neoPixelRoutine(int routine, int s, int value){
String params = String(value);
String strRoutine = params.substring(0,2);
String strWait = params.substring(2,4);
String strColor = params.substring(6,20);
if(routine == 101)
np_clear(s);
if(routine == 102)
np_setColor(s,getHashValue(value).toInt());
}
int np_clear(int s) {
return np_setColor(s,0);
}
int np_setColor(int s, uint32_t c) {
if(s==1){strip = strip1;} else if(s==2){strip = strip2;} else if(s==3){strip =
strip3;} else if(s==4){strip = strip4;} else return 0;
delay(wait);
delay(wait);
if(done == 0){
hashMapKeys[hashMapIndex] = key;
hashMapValues[hashMapIndex] = value;
hashMapIndex ++;
}
return 0;
}
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}