Help needed, crank signal generator. <solved>

MPC001
Posts: 174
Joined: Sat May 05, 2018 11:41 am

Re: Help needed, crank signal generator.

Post by MPC001 »

AngelMarc wrote: Sat Apr 26, 2025 1:24 pm A bunch of arbitrary syntax stuff.
I got it working less than a minute ago.
Just need to add back the speed variation input, then figure out some simple analog input hysteresis code.
And I might need to invert polarity.

Code: Select all

int TPS = 0;
int sequence[48] = {0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0};
int cam[48] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
int tooth = 0;
int low = 0;
int high = 0;
int RPMlow = 0;
int RPMhigh = 0;
int math = 1;
int halfdone = 1;
int done = 1;
int width = 1;
unsigned long previousmicros = 0;

void setup() {
//pinMode(A0, INPUT);
pinMode(1, OUTPUT);

}

void loop() {

if (halfdone == 0) {
  if (micros() - previousmicros >= RPMlow) {
      halfdone = 1;
      done = 0;
      digitalWrite(1, HIGH);
      previousmicros = micros();
    }
  }
if (done == 0) {
  if (micros() - previousmicros >= RPMhigh) {
      done = 1;
      math = 1;
      digitalWrite(1, LOW);
      previousmicros = micros();
    }
  }
   
if (math == 1) {
tooth++;
if (tooth == 48) {
  tooth = 0;
  }

TPS = 666; 
width = sequence[tooth];
cam[tooth];
if (width == 0) {
  low = 1;
  high = 2; 
  }
if (width == 1) {
    low = 2;
    high = 1;
  }
halfdone = 0;
math = 0;
RPMlow = low * TPS;
RPMhigh = high * TPS;
} 
}

Very interesting! While the 24X waveform looks correct for GM Gen III LS, I can't figure how you get that waveform from the 48 point array. If i run that array on an E40, while rpm is rock solid, the crank error logic gets upset.
User avatar
AngelMarc
Posts: 612
Joined: Sat Apr 08, 2023 11:23 am
cars: A CB450 running to 8,000RPM with a P59.

Re: Help needed, crank signal generator. <solved>

Post by AngelMarc »

Which microcontroller are you using? Performance seems to vary, more than just max speed. Best of what I have was the Pi Pico. And what are you using to step up the voltage? Pretty sure E40 is still 12 volt signal. Some of the variation of the TC44xx drivers invert the signal.

If it is just an inverted driver problem swapping these lines would do it.
digitalWrite(1, HIGH);
digitalWrite(1, LOW);

Code: Select all

if (halfdone == 0) {
  if (micros() - previousmicros >= RPMlow) {
      halfdone = 1;
      done = 0;
      digitalWrite(1, HIGH);
      previousmicros = micros();
    }
  }
if (done == 0) {
  if (micros() - previousmicros >= RPMhigh) {
      done = 1;
      math = 1;
      digitalWrite(1, LOW);
      previousmicros = micros();
    }
  }
  
Don't stress specific units.
User avatar
AngelMarc
Posts: 612
Joined: Sat Apr 08, 2023 11:23 am
cars: A CB450 running to 8,000RPM with a P59.

Re: Help needed, crank signal generator. <solved>

Post by AngelMarc »

int sequence[48] =
Is the 24x pattern twice, so one pass can have cam signal low and the other high.
A full array cycle is 2 crank rotations.
Don't stress specific units.
User avatar
AngelMarc
Posts: 612
Joined: Sat Apr 08, 2023 11:23 am
cars: A CB450 running to 8,000RPM with a P59.

Re: Help needed, crank signal generator. <solved>

Post by AngelMarc »

Code: Select all

if (width == 0) {
  low = 1;
  high = 2; 
  }
if (width == 1) {
    low = 2;
    high = 1;
  }
Dictates whether you get
Capture.PNG

or
Capture1.PNG
from
Capture2.PNG

Code: Select all

RPMlow = low * TPS;
RPMhigh = high * TPS;
Scales for different RPM

Code: Select all

if (halfdone == 0) {
  if (micros() - previousmicros >= RPMlow) {
      halfdone = 1;
      done = 0;
      digitalWrite(1, HIGH);
      previousmicros = micros();
    }

Is the low portion of tooth.

Code: Select all

if (done == 0) {
  if (micros() - previousmicros >= RPMhigh) {
      done = 1;
      math = 1;
      digitalWrite(1, LOW);
      previousmicros = micros();
    }
  }
Is the high portion.
If I remember right, I had to invert them because Arduino bug or something.

Code: Select all

if (math == 1) {
tooth++;
if (tooth == 48) {
  tooth = 0;
  }
Cycles through the array one at a time.

Code: Select all

int math = 1;
int halfdone = 1;
int done = 1;
Are just flags to dictate the order of each if statement.
You do not have the required permissions to view the files attached to this post.
Don't stress specific units.
User avatar
antus
Site Admin
Posts: 10012
Joined: Sat Feb 28, 2009 10:34 am
cars: TX Gemini 2L Twincam 8psi
TX Gemini SR20 18psi
Datsun 1200 Ute
Subaru Blitzen '06 EZ30 4th gen, 3.0R Spec B
Subaru WRX 2007

Re: Help needed, crank signal generator. <solved>

Post by antus »

Inversion depends on the configurarion of the gpio pin.
Have you read the FAQ? For lots of information and links to significant threads see here: http://pcmhacking.net/forums/viewtopic.php?f=7&t=1396
User avatar
AngelMarc
Posts: 612
Joined: Sat Apr 08, 2023 11:23 am
cars: A CB450 running to 8,000RPM with a P59.

Re: Help needed, crank signal generator. <solved>

Post by AngelMarc »

It did what it did by default, so I wrote my code different and moved on with my life.
Don't stress specific units.
MPC001
Posts: 174
Joined: Sat May 05, 2018 11:41 am

Re: Help needed, crank signal generator. <solved>

Post by MPC001 »

Thank you AngelMarc for the reply. Using an Arduino Nano @ 16meg with 5V I/O. So not the 133meg (?) clock speed of Pico RP2040. And yes realize E40 runs 12V CRK/CAM sensor supplies, but not confirmed that the signal lines were 5V or 12V and they run ok at 5V at present so didn't want to risk an expensive & hard to get E40 by driving at 12V without knowing for sure. (no live in car example to check with CRO.)

I did run up 120 point (Crank + Cam) arrays for 3 degree resolution state changes & the crank error logic stopped protesting. The crank speed is more stable without the CAM drive array in the loop, but then the CAM error logic of course complains. :)
AngelMarc wrote: Sat Jun 07, 2025 5:11 pm
Which microcontroller are you using? Performance seems to vary, more than just max speed. Best of what I have was the Pi Pico. And what are you using to step up the voltage? Pretty sure E40 is still 12 volt signal. Some of the variation of the TC44xx drivers invert the signal.
MPC001
Posts: 174
Joined: Sat May 05, 2018 11:41 am

Re: Help needed, crank signal generator. <solved>

Post by MPC001 »

:thumbup: Understood! :thumbup:
AngelMarc wrote: Sat Jun 07, 2025 5:22 pm int sequence[48] =
Is the 24x pattern twice, so one pass can have cam signal low and the other high.
A full array cycle is 2 crank rotations.
User avatar
AngelMarc
Posts: 612
Joined: Sat Apr 08, 2023 11:23 am
cars: A CB450 running to 8,000RPM with a P59.

Re: Help needed, crank signal generator. <solved>

Post by AngelMarc »

High speed square waves from a 32u4 (also 5 volt) start looking rounded. I don't remember what frequency that's noticable, but I don't see it at stupid speeds with the ESP32 S3 or the Pi Pico.
Don't stress specific units.
MPC001
Posts: 174
Joined: Sat May 05, 2018 11:41 am

Re: Help needed, crank signal generator. <solved>

Post by MPC001 »

Awesome! ThankYOU very much for taking the time to explain. Most appreciated. I suspected your additional code below was the answer but couldn't wrap my head around it. Will study in greater depth now till i get it. (I hadn't included originally with 48 point array as I didn't understand it. Doh!).

Originally I had written some "bit banger" (?) code (3 lines with a timer for EVERY state change - w/o an array) over a decade ago for an AVR Teensy 8 bit @ 8 meg., but the addition of the analogread for speed control disrupted the timing loop so much it would wouldn't maintain synch. (24x & 58x modes).

More modern silicon to the rescue!

Thankyou!

AngelMarc wrote: Sat Jun 07, 2025 5:31 pm

Code: Select all

if (width == 0) {
  low = 1;
  high = 2; 
  }
if (width == 1) {
    low = 2;
    high = 1;
  }
Dictates whether you get
Capture.PNG
or
Capture1.PNG
from
Capture2.PNG

Code: Select all

RPMlow = low * TPS;
RPMhigh = high * TPS;
Scales for different RPM

Code: Select all

if (halfdone == 0) {
  if (micros() - previousmicros >= RPMlow) {
      halfdone = 1;
      done = 0;
      digitalWrite(1, HIGH);
      previousmicros = micros();
    }

Is the low portion of tooth.

Code: Select all

if (done == 0) {
  if (micros() - previousmicros >= RPMhigh) {
      done = 1;
      math = 1;
      digitalWrite(1, LOW);
      previousmicros = micros();
    }
  }
Is the high portion.
If I remember right, I had to invert them because Arduino bug or something.

Code: Select all

if (math == 1) {
tooth++;
if (tooth == 48) {
  tooth = 0;
  }
Cycles through the array one at a time.

Code: Select all

int math = 1;
int halfdone = 1;
int done = 1;
Are just flags to dictate the order of each if statement.