I’m seeing explanations of using a FIFO, but I need something that works more like Vsync, where the most recent variable written by one core is available to the other. Making an engine controller with a Pi Pico. Already have crank signal decode sorted out.
I can explain most of the theoretical flow of logic if that matters.
I think you need to learn about concurrency.
Whenever you’re dealing with two or more processes reading or writing to the same data, you need to think about controlling how it’s shared.
I believe a paper like this one should be an okay overview:
There’s also concepts about producers and consumers that create and use data. If one process can handle waiting on the other, you can use something like a spin-lock or mutex (mutually-exclusive lock).
I haven’t looked into the best way of sharing data on the Pico specifically, but you can always add some kind of boolean flag or counter to your data structure that signifies when data is being written or read from the FIFO buffer.
In general with hard real-time applications (like audio processing or ignition timing), you need to limit the amount of time spent in the critical loop/callback function, and instead defer analytics and lower-priority tasks to the main-loop or secondary core.
With zero shared anything, core 2 is doing nothing.
You could be looking for a FILO…First In Last Out…
Yeah, but, does me no good if I can’t even get anything running on the 2nd core.
This is where I’m at at.
#define CRANK_SENSOR_PIN 2 // Pin connected to crankshaft sensor
volatile int readings[24] {4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095}; // Circular buffer
int bufIndex = 0; // Buffer index
long total = 4095 * 24; // Set this to the initial sum
volatile unsigned long lastTime = 0;
volatile unsigned long pulseHighTime = 0;
volatile unsigned long pulseLowTime = 0;
volatile uint8_t signalHistory = 0;
volatile bool newSample = false;
const uint8_t pattern0 = 0b00001111;
const uint8_t pattern1 = 0b01111101;
const uint8_t pattern2 = 0b11101110;
const uint8_t pattern3 = 0b01110011;
const uint8_t pattern4 = 0b10011000;
const uint8_t pattern5 = 0b11000101;
const uint8_t pattern6 = 0b00101000;
const uint8_t pattern7 = 0b01000001;
void handleCrankSignal() {
unsigned long currentTime = micros();
if (digitalRead(CRANK_SENSOR_PIN) == HIGH) {
pulseHighTime = currentTime - lastTime;
} else {
pulseLowTime = currentTime - lastTime;
uint8_t bit = (pulseHighTime > pulseLowTime) ? 0 : 1;
signalHistory = ((signalHistory << 1) | bit) & 0xFF;
digitalWrite(4, (signalHistory == pattern0) ? HIGH : LOW);
digitalWrite(5, (signalHistory == pattern1) ? HIGH : LOW);
digitalWrite(6, (signalHistory == pattern2) ? HIGH : LOW);
digitalWrite(7, (signalHistory == pattern3) ? HIGH : LOW);
digitalWrite(8, (signalHistory == pattern4) ? HIGH : LOW);
digitalWrite(9, (signalHistory == pattern5) ? HIGH : LOW);
digitalWrite(10, (signalHistory == pattern6) ? HIGH : LOW);
digitalWrite(11, (signalHistory == pattern7) ? HIGH : LOW);
newSample = true; // Signal to loop() to read ADC
}
lastTime = currentTime;
}
//Serial.begin(115200);
void setup() {
analogReadResolution(12);
//Serial.begin(115200);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(CRANK_SENSOR_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(CRANK_SENSOR_PIN), handleCrankSignal, CHANGE);
}
void setup1() {
Serial.begin(115200);
pinMode(A0, INPUT);
}
void loop() {
}
void loop1() {
if (newSample) {
newSample = false;
total -= readings[bufIndex];
int newVal = analogRead(A0);
readings[bufIndex] = newVal;
total += newVal;
bufIndex = (bufIndex + 1) % 24;
int avg12bit = total / 24;
int avg8bit = avg12bit >> 4;
Serial.println(avg8bit);
}
}
If I take out the shared variable so loop 2 just free runs, it still does nothing.
If I swap the labels, it works on core 1, but core 2 still fucks off.
1 cores job is nothing but the interrupt. I don’t need a strategy guide for utilizing processing power.
Well, good luck then.