#include <Arduino.h>
enum class State :uint8_t {
noop,
wait,
state1,
state2,
state3
};
State nextState;
State state;
uint32_t prevTime = millis();
uint32_t currentTime = millis();
uint32_t waitDelay;
void setup() {
Serial.begin(9600);
}
void nextStateAfter(State ss, uint32_t d) {
waitDelay = d;
nextState = ss;
state = State::wait;
prevTime = currentTime;
}
void loop() {
currentTime = millis();
switch (state) {
case State::noop:
//maybe wait for input? (for now just send anything to serial);
if (Serial.available() > 0) {
Serial.readString();
state = State::state1;
}
break;
case State::wait:
if (currentTime - prevTime > waitDelay) {
state = nextState;
prevTime = currentTime;
}
break;
case State::state1:
nextStateAfter(State::state2, 1000);
Serial.println("state1");
break;
case State::state2:
nextStateAfter(State::state3, 2000);
Serial.println("state2");
break;
case State::state3:
nextStateAfter(State::state1, 3000);
Serial.println("state3");
break;
}
}
// led pin
const int ledPin1 = 13;
// button pin
const int buttonPin1 = 2;
// blinking delay
const int interval1 = 500;
bool ledState1;
bool canBlink1;
unsigned long previousMillis1;
void setup() {
pinMode(ledPin1, OUTPUT); // set led pin to output
pinMode(2, INPUT_PULLUP); // button pin set to INPUT with internal PULLUP(default state will be HIGH)
}
void loop() {
unsigned long currentMillis = millis();
bool buttonState1 = digitalRead(buttonPin1);
if (buttonState1 == LOW) {
while (digitalRead(buttonPin1) == LOW);
if (digitalRead(buttonPin1) == HIGH) {
canBlink1 = !canBlink1;
digitalWrite(ledPin1, LOW);
}
}
if (currentMillis - previousMillis1 >= interval1 && canBlink1) {
previousMillis1 = currentMillis;
ledState1 = !ledState1;
digitalWrite(ledPin1, ledState1);
}
}
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() {
}
After some time of googling, i found interesting solution, how to get and set pins as bits in arduino
union myunion {
struct {
unsigned int b7: 1;
unsigned int b6: 1;
unsigned int b5: 1;
unsigned int b4: 1;
unsigned int b3: 1;
unsigned int b2: 1;
unsigned int b1: 1;
unsigned int b0: 1;
};
unsigned int num;
} mu;
with this union with struct, we can read pins to 1 big number invidual bits and display it on for example - led's in binary.
mu.b0 = digitalRead(2);
mu.b1 = digitalRead(3);
mu.b2 = digitalRead(4);
mu.b3 = digitalRead(5);
mu.b4 = digitalRead(6);
mu.b5 = digitalRead(7);
mu.b6 = digitalRead(8);
mu.b7 = digitalRead(9);
and vuola, now we can get number with "mu.num" depending on HIGH pins
Serial.println(mu.num);
and in reverse, we can set "mu.num = 127" and write individual bits to pins.
digitalWrite(mu.b0);
digitalWrite(mu.b1);
digitalWrite(mu.b2);
digitalWrite(mu.b3);
digitalWrite(mu.b4);
digitalWrite(mu.b5);
digitalWrite(mu.b6);
digitalWrite(mu.b7);
whole program:
// parallel to serial
// serial to parallel
union mu1 {
struct {
unsigned int b7: 1;
unsigned int b6: 1;
unsigned int b5: 1;
unsigned int b4: 1;
unsigned int b3: 1;
unsigned int b2: 1;
unsigned int b1: 1;
unsigned int b0: 1;
};
unsigned int num;
} mu;
void setup() {
Serial.begin(9600);
}
void loop() {
mu.b0 = digitalRead(2); // switch 1
mu.b1 = digitalRead(3); // switch 2
mu.b2 = digitalRead(4); // switch 3
mu.b3 = digitalRead(5); // switch 4
mu.b4 = digitalRead(6); // switch 5
mu.b5 = digitalRead(7); // switch 6
mu.b6 = digitalRead(8); // switch 7
mu.b7 = digitalRead(9); // switch 8
Serial.println(mu.num);
delay(5000);
}
thats it. union acts as "shift in" and "shift out" register, if you set mu.num than you can read individual bits(pins) if you set pins you can read mu.num and it works then like shift in register.
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);
}
}
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