Hi, I've got a timer function that decreases the time on the LCD each time it's called, then I'm calling a function that does the "Knight Rider" sort of effect on the neopixel 8x, it takes exactly 1 second till the led moves to right and one second till it comes to left. It works fine and all but it's using the delay function that pauses everything else and I need to do some other things in the main loop too, so I looked for a way to "multithread" the functions but I found out that multithreading is impossible on the arduino uno and i can only do protothreading, for which i can't really use the for loop. So i splitted the whole for loop into multiple if statements and followed the "Blink without Delay" example. However the delay is not constant, it moves 2x slower and sometimes it moves faster and so on. I'm not really sure where i made the mistake.
prop "bomb" for airsoft games.
#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Adafruit_NeoPixel.h>
#define PIN 6 // input pin Neopixel is attached to
#define NUMPIXELS 8 // number of neopixels in strip
const byte ROWS = 4;
const byte COLS = 3;
unsigned long prevTime = 0;
char hexaKeys[ROWS][COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[ROWS] = {A5, A4, A3,A2};
byte colPins[COLS] = {A1,A0,2};
Keypad kp = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
//LCD setup
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
void lcdSetup(){
lcd.begin(16,2);
lcd.clear();
}
bool bomb;
char bCode[4];
int buzzer = 7;
//int hr,min,sec;
namespace timer{
int timeArr[6];
long timeSec;
int timeRem[3];
bool finished;
long convertTimeToMs(int *input){
long retval = 0;
retval += (long)input[0]*60*60;
retval += (long)input[1]*60;
retval += input[2];
return retval;
}
void bombGetTimer(int *curTimer, int *remTime){
bool getInput;
int s=0;
lcd.clear();
lcd.print("Time:");
lcd.setCursor(0,1);
lcd.print("00:00:00");
for(int i = 0;i<6;i++){
if(i<=2 && i>1)
s=1;
if(s==1 && i==1)
s=0;
if(s==2 && i==3)
s=1;
if(i>=4)
s=2;
lcd.setCursor(i+s,1);
lcd.print("0");
lcd.setCursor(i+s,1);
lcd.blink();
getInput = false;
while(!getInput){
char tempKey = kp.getKey();
if(tempKey != NO_KEY && tempKey != '*' && tempKey != '#'){
tone(buzzer, 500,10);
curTimer[i] = (int)tempKey-48;
lcd.print(tempKey);
getInput = true;
}
if(tempKey == '*' && i){
tone(buzzer, 500,10);
i-=2;
getInput = true;
}
}
lcd.noBlink();
}
remTime[0] = (curTimer[0]*10)+curTimer[1];
remTime[1] = (curTimer[2]*10)+curTimer[3];
remTime[2] = (curTimer[4]*10)+curTimer[5];
}
bool timerLogic(long &seconds){
lcd.setCursor(0,0);
lcd.print("REMAINING: ");
lcd.setCursor(0,1);
if(seconds/3600<10){
lcd.print("0");
}
lcd.print(seconds/3600);
lcd.print(":");
lcd.setCursor(3,1);
if((seconds/60)%60<10){
lcd.print("0");
}
lcd.print((seconds/60)%60);
lcd.print(":");
lcd.setCursor(6,1);
if(seconds%60 < 10){
lcd.print("0");
}
lcd.print(seconds % 60);
seconds--;
if(!seconds)
return true;
return false;
}
};
void bombGetCode(char *code){
bool getInput;
lcd.setCursor(0,0);
lcd.print("4 Digits code");
lcd.setCursor(0,1);
lcd.print("XXXX");
for(int i = 0; i<4;i++){
getInput = false;
while(!getInput){
char tempKey = kp.getKey();
if(tempKey != NO_KEY && tempKey != '*' && tempKey != '#'){
tone(buzzer, 500,10);
lcd.setCursor(i,1);
code[i] = tempKey;
lcd.print(code[i]);
getInput = true;
}
}
}
}
void runMain(){
lcd.print("Select mode.");
lcd.setCursor(0,1);
lcd.print("1: Bomb | 2: -->");
while(!bomb){
if(kp.getKey() == '1')
bomb = true;
}
if(bomb){
timer::bombGetTimer(timer::timeArr,timer::timeRem);
timer::timeSec = timer::convertTimeToMs(timer::timeRem);
delay(1000);
lcd.clear();
lcd.print("BOMB SELECTED");
delay(500);
bombGetCode(bCode);
}
}
void setup(){
Serial.begin(9600);
pixels.begin();
pinMode(buzzer, OUTPUT);
lcdSetup();
runMain();
}
void movePix(int i,unsigned long currentMillis){
pixels.setPixelColor(i-1, pixels.Color(0, 0, 0));
pixels.setPixelColor(i, pixels.Color(255, 0, 0));
pixels.show();
prevTime = currentMillis;
}
void backPix(int i,unsigned long currentMillis){
pixels.setPixelColor(i+1, pixels.Color(0, 0, 0));
pixels.setPixelColor(i, pixels.Color(255, 0, 0));
pixels.show();
prevTime = currentMillis;
}
void testStripe(int delaysec){
unsigned long currentMillis = millis();
static int i = 0;
static bool rep = true;
if(rep){
if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==0){
movePix(i,currentMillis);
i++;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==1){
movePix(i,currentMillis);
i++;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==2){
movePix(i,currentMillis);
i++;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==3){
movePix(i,currentMillis);
i++;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==4){
movePix(i,currentMillis);
i++;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==5){
movePix(i,currentMillis);
i++;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==6){
movePix(i,currentMillis);
i++;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==7){
movePix(i,currentMillis);
timer::timerLogic(timer::timeSec);
rep = !rep;
}
}
if(!rep){
if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==7){
backPix(i,currentMillis);
i--;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==6){
backPix(i,currentMillis);
i--;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==5){
backPix(i,currentMillis);
i--;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==4){
backPix(i,currentMillis);
i--;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==3){
backPix(i,currentMillis);
i--;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==2){
backPix(i,currentMillis);
i--;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==1){
backPix(i,currentMillis);
i--;
}
else if(currentMillis-prevTime >=delaysec/NUMPIXELS && i==0){
backPix(i,currentMillis);
timer::timerLogic(timer::timeSec);
rep = !rep;
}
}
}
void delayPixelStripe(int delaysec){
static bool test = true;
unsigned long currentMillis = millis();
if(test)
{
for(int i=0;i<NUMPIXELS;i++){
pixels.setPixelColor(i-1, pixels.Color(0, 0, 0));
pixels.setPixelColor(i, pixels.Color(255, 0, 0));
pixels.show();
//delay(delaysec/NUMPIXELS);
}
}
if(!test){
for (int i = NUMPIXELS; i --> 0; ){
if(currentMillis - prevTime >= delaysec/NUMPIXELS){
pixels.setPixelColor(i+1, pixels.Color(0, 0, 0));
pixels.setPixelColor(i, pixels.Color(255, 0, 0));
pixels.show();
//delay(delaysec/NUMPIXELS);
}
}
}
test = !test;
}
void loop(){
unsigned long curTime = millis();
if(bomb){
char customKey = kp.getKey();
if(customKey)
Serial.println("Detected");
//timer::finished = timer::timerLogic(timer::timeSec);
testStripe(1000/2);
}
}