I'm using an Arduino Uno to output a frequency to move the speedometer gauge from an information cluster.
Every time i send a serial message (to update the speed and such), the gauge gets moved back a little bit
I presume it's because serial communication uses interrupts.
Is there any way to fix this issue? Here's my code in it's entirety.:
//0.7hz per km/h
//0.1hz per 1000rpm
//A0 - right blinker
#define rBlinker A0
#define lBlinker A1
#define lLights A2
#define ABS A3
#define lowFuel A4
#define speedo 2
#define tacho 3
#define fuel 10
#define temp 5
long speedodelay;
long tachodelay;
long fueldelay;
int currSpeed;
int currRPM;
int currFuel;
unsigned long previousMicros = 0;
unsigned long previousMicrosT = 0;
bool fuelState;
void setup() {
// put your setup code here, to run once:
pinMode(rBlinker, OUTPUT);
pinMode(A2, OUTPUT);
pinMode(A3, OUTPUT);
pinMode(A4, OUTPUT);
pinMode(A5, OUTPUT);
pinMode(A1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
Serial.begin(115200);
Serial.setTimeout(50);
}
void loop() {
// put your main code here, to run repeatedly:
//digitalWrite(rBlinker, HIGH);
noInterrupts();
tachoLoop();
speedoLoop();
interrupts();
if(Serial.available()) {
String msg = Serial.readString();
Serial.println(msg.charAt(0));
switch(msg.charAt(0)) {
case 's':
{
msg.remove(0, 1);
currSpeed = msg.toInt();
float frequency = currSpeed * 0.7;
float period = 1 / frequency;
speedodelay = period * 1000000;
}
break;
case 't':
{
msg.remove(0, 1);
currRPM = msg.toInt();
float frequencyT = currRPM * 0.033;
float periodT = 1 / frequencyT;
tachodelay = periodT * 1000000;
}
break;
case 'f':
{
msg.remove(0, 1);
currFuel = msg.toInt();
float frequencyF = currFuel * 0.04;
float periodF = 1 / frequencyF;
fueldelay = periodF * 1000000;
Serial.println(msg);
}
break;
case 'b':
{
msg.remove(0, 1);
int state = msg.charAt(1) == '1' ? 1 : 0;
if(msg.charAt(0) == 'l') {
digitalWrite(lBlinker, state);
}
else {
digitalWrite(rBlinker, state);
}
Serial.println(msg.charAt(1));
}
break;
}
}
int fuelPWM = map(currFuel, 0, 100, 110, 240);
analogWrite(5, 140); // water temp, 120 is middle, 140 is maax, 100 is 0
analogWrite(10, fuelPWM); // fuel level, 170 - middle, 240 - full, 110 - empty
}
void speedoLoop() {
unsigned long currentMicros = micros();
if(currentMicros - previousMicros >= speedodelay / 2) {
previousMicros = currentMicros;
digitalWrite(speedo, !digitalRead(speedo));
}
}
void tachoLoop() {
unsigned long currentMicrosT = micros();
if(currentMicrosT - previousMicrosT >= tachodelay / 2) {
previousMicrosT = currentMicrosT;
digitalWrite(tacho, !digitalRead(tacho));
}
}
I'm fully aware that it's really ugly, and i'm sorry for that.