Hey everyone, this is my first time creating an argument here. I built a quickshifter for my motorcycle (i don't know if you are familiar with it). Its fuction is not hard, it reads the TPS sensor of the throttle, and it reads the number of impulses from the negative wire of the ignition coil (with an appropriate circuit, which uses an optocoupler), which i use to basically read the engine RPMs. Based on these two inputs values, the program changes the duration of the power cutoff. The ignition coil is a CDI. The power is cutted off when i press a switch (which is normally open, and becomes closed when pressed) implemented in the shifter rod, it is a switch specifically designed for quickshifters. The cutoff works in the following way: my circuit enables an IGBT transistor which grounds the negative wire of the coil (so it charges the ignition coil and therefore the spark plug doesn't emit any sparks). My issue is that when the engine is running, raspberry pi pico is not detecting at all the quickshifter switch (which works perfectly fine because i tested it with the multimeter). In the current version, i don't use any interrupts, however i tested it with also interrupts and it SOMETIMES detected the pressing of the switch. The other parts of the circuit work well, except for the RPMs reader that works correctly only above 2400rpms.
Here's the code, i used earlephilhower's library for the pi pico, which enables the usage of both cores:
#define SENSIN 18 // INPUT PEDAL SHIFTER SWITCH SENSOR
#define SENSRPM 22 // INPUT PIN OPTOCOUPLER FOR READING RPMs
#define SPARKCUT 21 // OUTPUT PIN FOR THE TC4427AEPA
#define TPS_IN 26 //INPUT PIN A0 TO READ THE ANALOG TPS SIGNAL, which goes from 0v to 5v, at 5v the TPS equals to 100%
#define LEDPIN LED_BUILTIN // LED on Pi Pico
unsigned long int ultimo_cambio = 0;
unsigned int rpm = 0, rps = 0, rpm_min, intervallorpm = 0, tps = 0, intervallo_cambio, cutoff_offset;
volatile int statosens = 0;
/* Matrix to host the cutoff duration values of the coil, from bottom to top we have the TPS in increasing percentage
while from left to right we have the engine revs in increasing order. All numbers are in milliseconds.*/
/* 5 because the TPS resolution is 20% (5 / 100), the resolution can be further improved: (num. of rows / 100) */
/* 7 columns for the RPM resolution. It starts at 3000 RPM, each column is increased by 1000 giri, up to 10000 RPM. The engine rev limiter is set at 10500 RPM.
C1 >= 3000 && < 4000, C2 >= 4000 && < 5000, C3 >= 5000 && < 6000, C4 >= 6000 && < 7000, C5 >= 7000 && < 8000, C6 >= 8000 && < 9000, C7 >= 9000 && < 10500 (rev limiter RPMs) */
unsigned int cutoff[5][7] = {
/* R5 */ { 90, 80, 75, 72, 70, 65, 60}, // TPS > 80% && <= 100%
/* R4 */ {100, 90, 85, 80, 75, 72, 70}, // TPS > 60% && <= 80%
/* R3 */ {115, 105, 90, 85, 82, 80, 75}, // TPS > 40% && <= 60%
/* R2 */ {130, 115, 105, 100, 95, 93, 90}, // TPS > 20% && <= 40%
/* R1 */ {140, 135, 130, 120, 110, 105, 100} // TPS >= 0% && <= 20%
/* || || || || || || ||
C1 C2 C3 C4 C5 C6 C7 */
};
void setup(){
Serial.begin(9600);
pinMode(SENSRPM, INPUT_PULLUP);
pinMode(TPS_IN, INPUT);
pinMode(SENSIN, INPUT_PULLUP);
pinMode(SPARKCUT, OUTPUT);
pinMode(LEDPIN, OUTPUT);
// Config variables
intervallo_cambio = 250; // Debouncing value for the pedal switch sensor
rpm_min = 3500; // RPM Value used to set a minimum RPM to use the quickshifter. A lower RPM Value could damage the gearbox when using lower gears (first and second gears for instance)
// Added value to increase or decrease the total amount of the cutoff time
cutoff_offset = 5;
// End of config variables
ultimo_cambio = millis();
tps = 100;
}
void setup1(){
digitalWrite(SPARKCUT, LOW);
digitalWrite(LEDPIN, LOW);
}
void loop(){
Serial.print("\n Core 0");
conta_giri(); // Function to read RPMs from the optocoupler signal
tps = map(analogRead(TPS_IN), 0, 1023, 0, 100); // Reads the TPS signal which goes from 0 to 1023 and the converts it to a percentage which goes from 0% up to 100%
// Debug prints
Serial.print("\n RPM = ");
Serial.print(rpm);
Serial.print("\n TPS = ");
Serial.print(tps);
Serial.print("\n cut: ");
Serial.print(cutoff[cutoff_riga(tps)][cutoff_colonna(rpm)] + cutoff_offset);
Serial.print("\n riga: ");
Serial.print(cutoff_riga(tps));
Serial.print("\n colonna: ");
Serial.print(cutoff_colonna(rpm));
Serial.print("\n\n");
// End of debug prints
}
void loop1(){
if((digitalRead(SENSIN) == LOW) && (statosens == 1)){
digitalWrite(SPARKCUT, HIGH); // Sets the signal of the TC4427 to HIGH, enabling the IGBT gate and therefore cuts the power of the ignition coil
digitalWrite(LEDPIN, HIGH);
delay(cutoff[cutoff_riga(tps)][cutoff_colonna(rpm)] - cutoff_offset); // Delay which gets the values of the cut-off duration from the matrix
digitalWrite(SPARKCUT, LOW); // Sets the signal of the TC4427 to LOW, so that the IGBT is LOW and doesn't cut off the power of the ignition coil
digitalWrite(LEDPIN, LOW);
Serial.print("\n stato sens"); // debug
ultimo_cambio = millis(); // Sets this variable to the last time the power was cutted off so that we can use the debounce to avoid multiple presses of the switch
statosens = 0; // this value indicates that the gear shfit sensor has been pressed, and it is set to zero when it is pressed
}
if (((millis() - ultimo_cambio) > intervallo_cambio) && (digitalRead(SENSIN) == HIGH)){
statosens = 1; // if the debounce time was surpassed and the shift sensor is not pressed, the value is set to one so that we can use it again
}
else if(digitalRead(SENSIN) == LOW){
ultimo_cambio = millis(); // if the previous condition is not met, and the shift sensor is still pressed, we reset the timer
}
}
void conta_giri(){ // i found this browsing the arduino forum
Serial.print("\n cunta giri");
intervallorpm = pulseIn(SENSRPM, HIGH, 100000) + pulseIn(SENSRPM, LOW, 100000);
rps = 1000000UL/intervallorpm; //rps is roations per second
rpm = (rps*60)*2; //rpm is rotations per minute, which is multiplied by two because the engine is a 4 stroke, therefore i have a spark event every 720 crankshaft degrees, if i don't multiply it by 2 the programs gives me the exact half of the actual rpms
if(rpm>10600) // Problem to solve: under 2400 rpm the program reads random rpms above 12 thousand rpms. So if the revs are higher than the limiter (10500), I reset them to make the program work properly
rpm = 0;
}
int cutoff_colonna(int rpm){
/* selection construct to choose the column of revolutions (x axis), to be modified in case of change in the number of columns of the matrix */
if((rpm >= 3000) && (rpm < 4000))
return 0;
else if ((rpm >= 4000) && (rpm < 5000))
return 1;
else if ((rpm >= 5000) && (rpm < 6000))
return 2;
else if ((rpm >= 6000) && (rpm < 7000))
return 3;
else if ((rpm >= 7000) && (rpm < 8000))
return 4;
else if ((rpm >= 8000) && (rpm < 9000))
return 5;
else if ((rpm >= 9000) && (rpm < 105000))
return 6;
else
return 0; // In case of any problem, the program returns the lowest column which has the highest cutoff time
}
int cutoff_riga(int tps){
/* selection construct to choose the row of the TPS (y axis), to be modified in case of variation of the number of rows of the matrix */
if((tps >= 0) && (tps <= 20))
return 4;
else if ((tps > 20) && (tps <= 40))
return 3;
else if ((tps > 40) && (tps <= 60))
return 2;
else if ((tps > 60) && (tps <= 80))
return 1;
else if ((tps > 80) && (tps <= 100))
return 0;
else
return 4; // In case of any problem, the programs returns the row (the bottom one), which has the highest cutoff time
}
and here's the electric diagram, which has more electric components that i hanve't described:
Let me know if you have any kind of solution! The power is cutted of perfectly and i have zero issues of shortcircuits or other electrical kind of issues. Thanks a lot in advance!