Golang and Arduino

Small arduino and golang programs

Golang sync cond example

golang sync cond working example


package main

import (
    "sync"
    "time"
)

var mu = sync.Mutex{}
var sc = sync.NewCond(&mu)

var setME string

func main() {
    go func() {
        for {

        }
    }()

    // start 10 gourintines

    for i := 0; i < 10; i++ {
        go func(i int) {
            println("go routine started")
            sc.L.Lock()
            sc.Wait()
            println(setME, "release", i)
            sc.L.Unlock()

        }(i)
    }
    time.Sleep(1 * time.Second)

    // set variable and
    // signal sync.cond to release 3 random locks
    // from waiting go routines

    for i := 0; i < 3; i++ {
        sc.L.Lock()
        setME = "test signal"
        sc.Signal()
        sc.L.Unlock()
    }
    time.Sleep(2 * time.Second)

    // release all waiting go routines to use global variable
    sc.L.Lock()
    setME = "test broadcast"
    sc.Broadcast()
    sc.L.Unlock()

    time.Sleep(3 * time.Second)
}

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