Thanks for taking a look! It's very much appreciated, this whole thing has been a mixture of nightmare and ecstasy hahaha
alto777:
Also: do you not need to
while (!P.animate())
;
in the places where you don't hold it in a while loop?
Like perhaps at the end of displaySetup, where you reset and clear the disaply if you've finished the animation, and you don't if you haven't. This is not what you want I think.
You're right, I quickly realised this when the StartupText was being skipped!
I've updated that along with passing a HARDWARE_TYPE to MD_Parola as something has changed between the library versions to necessitate it.
It's now displaying, and the StartupText is scrolling but the behaviour with gear switching is not behaving as expected.
Instead of starting with "P", it shows "R" and the detection is sporadic and mostly incorrect.
I'll try a version that incorporates the suggestions you've given - I like your idea of switching the print and scroll functions as it's much simpler, but a couple of other variables change also and as far as I'm aware the displayAnimate is called differently.
I.e.:
To Print:
P.displayText(GearChars[x], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
P.displayAnimate();
To Scroll:
P.displayText(GearChars[x], PA_CENTER, 50, 1, PA_SCROLL_UP, PA_NO_EFFECT);
while (!P.displayAnimate())
;
Note that 0, 0 becomes 50, 1.
Is there anything you can see in my getGear or displayGear functions that would cause issues? I feel like I may have broken the logic somewhere along the way...
Latest:
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <CircularBuffer.h>
#define HARDWARE_TYPE MD_MAX72XX::GENERIC_HW
#define MAX_DEVICES 1 // number of LED modules, should always be one
#define CLK_PIN 13 // which pin on Arduino is wired to LED's CLK pin
#define DATA_PIN 11 // which pin on Arduino is wired to LED's DATA pin
#define CS_PIN 10 // which pin on Arduino is wired to LED's CS pin
// constants won't change:
const int NUM_HALL = 6; // set this to match the number of hall sensors
const int Hall[] = {3, 4, 5, 6, 7, 8}; // set to match wiring of sensors to their pins
const int NUM_GEARS = 7; // how many gears are used
// c-string for each gear, Parola lib requires for animation ([2] reserves 2 bytes for char and terminating '\O')
const char GearChars[NUM_GEARS][2] = {"P", "R", "N", "D", "3", "2", "1"}; // layout here from left to right should match gear order on vehicle from top to bottom
const char StartupText[] = "Startup Text"; //text scrolled upon boot
const int BRIGHTNESS = 4; // set brightness of LEDs (0-15), can replace with potentiometer-derived value
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// variables will change:
int hallState[NUM_GEARS];
int prevGear = 0;
int currentGear = 0;
int hallTotal = 0;
CircularBuffer<int, 4> previousGear; // use a buffer to store last 4 gear positions
//4 used here as buffer will be used to detect 'sequence' such as 1-2-1-2, which can then be acted upon
// initialize the hall effect sensor pins as inputs:
void hallSetup() {
for (int i = 0; i < NUM_HALL; i++) {
pinMode(Hall[i], INPUT);
}
}
// setup LED display
void displaySetup() {
P.begin(); // initialise display
P.setIntensity(BRIGHTNESS); //set display intensity/brightness (0-15)
P.displayClear();
P.displayText(StartupText, PA_CENTER, 100, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT); // display message on startup
while (!P.displayAnimate())
;
P.displayReset();
P.displayClear();
// previousGear.push(0);
}
// loop through all sensors once and record to array - includes 'fake' sensor as first value to represent 'P'
// then translates reading to relevant character by checking for non-zero value
int getGear() {
for (int i = 1; i < NUM_HALL + 1; i++) {
hallState[i] = digitalRead(Hall[i - 1]);
if (hallState[i] == HIGH) {
hallTotal = hallTotal + 1;
previousGear.push(i); // stores current gear in buffer at the end, overwriting old data if necessary
return i; //returns current loop iteration, which represents currentGear's location in GearChars array
}
}
if (hallTotal == 0) { // if no HIGH readings, must be in 'P'
previousGear.push(0); // stores current gear in buffer
return 0; // returns 0 which represents 'P' location in GearChar array
}
}
// displays current gear on LED, checks if animations should be used depending on previous (if any) gear value
void displayGear(int x) {
if (previousGear.isEmpty() || x == previousGear.last()) { // if no previous value or same as previous, simply print
P.displayText(GearChars[x], PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
P.displayAnimate();
}
else if (previousGear.last() < currentGear) { // if prev gear value exists AND is not the same as previous value
// if the previous gear is situated to the left of current gear (in char array) then scroll up
P.displayText(GearChars[x], PA_CENTER, 50, 1, PA_SCROLL_UP, PA_NO_EFFECT);
while (!P.displayAnimate())
;
// if the previous gear is not situated left (i.e. is to the right of current gear in char array) then scroll down
} else {
P.displayText(GearChars[x], PA_CENTER, 50, 1, PA_SCROLL_DOWN, PA_NO_EFFECT);
while (!P.displayAnimate())
;
}
}
}
void setup() {
hallSetup();
displaySetup();
}
void loop() {
currentGear = getGear();
displayGear(currentGear);
}