Golang and Arduino

Small arduino and golang programs

Make a simple scheduler for arduino

After some googling, i decided to try to write and arduino library to simplify use of "millis" trick to schedule jobs with 'clean api'.

Here is some code of blink:


#include "SimpleScheduler.h"

void ledOn();
void ledOff();

void ledOn() {
  digitalWrite(LED_BUILTIN, HIGH);
  schedule(500, ledOff);
}
void ledOff() {
  digitalWrite(LED_BUILTIN, LOW);
  schedule(500, ledOn);
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  ledOn();
}

void loop() {
  scheduler_run();
}

you can find library at github arduino SimpleScheduler

arduino parse hex colors to numbers


void setup() {
    Serial.begin(9600);

    // get data from Serial.readStringUntil('\n'); to memory
    String data="FFFFFFFF 00FFFFFF 0000FFFF 000000FF";
    // store length of data
    int iend = data.length() - 1; 
    // current begin index
    int index=0;
    // next index
    int next_index;
    do{
        next_index=data.indexOf(' ',index);

        String hexcode=data.substring(index, next_index);

        index=next_index+1;

        unsigned long bigNumber = (unsigned long)strtoul(hexcode.c_str(), 0, 16);

        // add number to array

        Serial.println(bigNumber);

     }while((next_index!=-1)&&(next_index<iend));
}

void loop() {

}

arduino read serial command and parse to variables

You can send command without any libraries to arduino. in this example "message" ( protocol) is "2 chars + number + number" -> "GO 123 -512" 


void setup() { Serial.begin(9600); } void loop() {
// check if something on Serial if(Serial.available()) {
// define variables long number1, number2; char cmd[2]; memset(cmd, 0, 2);
// read data from Serial String s = Serial.readStringUntil('\n'); char buff[64]; memset(buff, 0, 64);
// convert string to char array s.toCharArray(buff, 64);
// parse cmd to variables sscanf(buff, "%2c %ld %ld",cmd, &number1, &number2); char pr[128]; memset(pr, 0, 128);
// print template to buffer sprintf(pr, "got 2 numbers from serial: %ld and %ld and command %s", number1, number2, cmd);
// print buffer back to Serial Serial.println(pr); } }

Protothreads on tinkercad

using arduino protothreads in tinkercad

Just copy following lines to begin of tinkercad code

#define LC_INIT(lc)
struct pt { unsigned short lc; };
#define PT_THREAD(name_args)  char name_args
#define PT_BEGIN(pt)          switch(pt->lc) { case 0:
#define PT_WAIT_UNTIL(pt, c)  pt->lc = __LINE__; case __LINE__: \
                              if(!(c)) return 0
#define PT_END(pt)            } pt->lc = 0; return 2
#define PT_INIT(pt)   LC_INIT((pt)->lc)

Simple program with 2 different delays


#define LC_INIT(lc)
struct pt { unsigned short lc; };
#define PT_THREAD(name_args) char name_args
#define PT_BEGIN(pt) switch(pt->lc) { case 0:
#define PT_WAIT_UNTIL(pt, c) pt->lc = __LINE__; case __LINE__: \
if(!(c)) return 0
#define PT_END(pt) } pt->lc = 0; return 2
#define PT_INIT(pt) LC_INIT((pt)->lc)



struct pt pt1;
struct pt pt2;

void setup() {
Serial.begin(9600);
while(!Serial);
PT_INIT(&pt1);
PT_INIT(&pt2);
}

void loop() {
test(&pt1);
test2(&pt2);
}

unsigned long timeNow = 0;
PT_THREAD(test(struct pt *pt)) {
PT_BEGIN(pt);
timeNow = millis();
PT_WAIT_UNTIL(pt, millis() - timeNow > 5000);
Serial.println("print test1");
PT_END(pt);
}


unsigned long timeNow2 = 0;
PT_THREAD(test2(struct pt *pt)) {
PT_BEGIN(pt);
timeNow2 = millis();
PT_WAIT_UNTIL(pt, millis() - timeNow2 > 1000);
Serial.println("print test2");
PT_END(pt);
}

Thats it! Now you have pretty syntax instead of arduino millis() trick to delay tasks.

You can read more about protothreads http://dunkels.com/adam/pt/expansion.html