0
\$\begingroup\$

Can someone please help me with code? I have a 24 teeth trigger wheel. Every tooth is registered by hall sensor and I need that Arduino simulate 36 pulse output of that corresponding 24 pulse input.

Here is my code with delayMicroseconds, but I can`t use delayMicroseconds, because Arduino doesn't understand bigger than 16k micros delay.

const int  hall = 2;    // hall sensor
const int ledPin = 13;       // the pin that the LED is attached to

// Variables will change:
int teethCounter = 0;
int hallState = 0;
int lasthallState = 0;
long cycles=0;
boolean cycle = false;
unsigned long microsStart = 0;
unsigned long microsStop = 0;
unsigned long usElapsed = 0;
unsigned long usElapsedUp = 0;
unsigned long usInterval;


void setup() {
// initialize the button pin as a input:
pinMode(hall, INPUT);
// initialize the LED as an output:
pinMode(ledPin, OUTPUT);
// initialize serial communication:
Serial.begin(9600);
}


void loop() {
hallState = digitalRead(hall);
if(cycle==true){
microsStart=micros();
}
if(cycle==true){
usInterval = usElapsedUp/72;
for (int i=0; i <= 36; i++){
digitalWrite(13,HIGH);
delayMicroseconds(usInterval);
digitalWrite(13,LOW);
delayMicroseconds(usInterval);
cycle = false;
}
}

 // compare the hallState to its previous state
 if (hallState != lasthallState) {
 // if the state has changed, increment the counter
 if (hallState == HIGH) {
 teethCounter++;
 if(teethCounter==24){
 cycle = true;
 cycles++;
 teethCounter=0;
 usElapsedUp = usElapsed;

 }

 Serial.print("Tooth count: ");
Serial.print(teethCounter);
Serial.print(" Cycles: ");
Serial.print(cycles);
Serial.print(" Time: ");
Serial.print(usElapsedUp);
Serial.print(" Interval: ");
Serial.println(usInterval);
}
microsStop=micros();
usElapsed=microsStop-microsStart;
}
// save the current state as the last state,
//for next time through the loop

lasthallState = hallState;
}

How can I calculate and from where can I take trigger points?

  If(event happens==true){
  digitalWrite(13,HIGH);
   }
  If(event happens==false){
  digitalWrite(13,LOW);
  }

If it helps

\$\endgroup\$
  • \$\begingroup\$ What timing resolution do you need? - A simple implementation would be to output 3 pulses every time you see two pulses coming in. The timing of the 3 pulses could always be the same. Or you may need to implement a digital phase locked loop to create a constant frequency output at 3/2 times the input frequency. \$\endgroup\$ – Kevin White Jun 13 '17 at 21:12
  • \$\begingroup\$ For that application you probably don't care if the pulses are equally spaced in time. \$\endgroup\$ – Kevin White Jun 13 '17 at 21:36
  • \$\begingroup\$ I swapped gearbox on my car, from newer model, its mechanicaly same, but it has an upgrade from vr sensor to hall and the hall sensor are in different spot, and it uses 24 teeth trigger wheel. Old gearbox used vr sensor and 36 teeth trigger wheel. So I need to simulate 36 tooth output into TCU(transmission control unit) from that 24 teeth wheel. In one revolution I get 24 HIGH pulses and 24 LOW pulses, and somehow need to convert that with Arduino to output 36 HIGH pulses and 36 LOW pulses to feed into TCU. \$\endgroup\$ – Ralfs Volis Jun 13 '17 at 21:43
1
\$\begingroup\$

schematic

simulate this circuit – Schematic created using CircuitLab

Frequency doubling is easy enough by triggering on every change of state of the input signal (a) for a fixed time resulting in waveform (b). It should be fairly trivial coding to pass this through to the output but mute every fourth pulse to give you three out for every two in.


schematic

simulate this circuit

Figure 2. A three-phase clock (a), (b) and (c) gives 72 pulses/rev (d) which can be divided by two to give 36 pulses/rev.

Another option to get accurate timing is to use three sensors offset by an integer number of teeth + 5° and + 10° (1/3 tooth and 2/3 tooth). This will give you 72 pulse per revolution and you can divide by two to get 36 (e).


I'd recommend that you don't use built-in delay functions. Your code can't do anything else in the meantime. Create timers and check on each scan to see if they have elapsed.

\$\endgroup\$
1
\$\begingroup\$

I'm not sure you need to play with the pulses at all. Since you have an Arduino receiving the pulses, you can create any output pulse rate you want for any given single revolution of the gear.

  1. Count 24 (or any number you want) inbound pulses on the Arduino.
  2. Calculate the time for one revolution, divide by 36.
  3. Program a timer for the calculated pulse rate.
  4. Output 36 pulses at the calculated rate.

This would output pulses at a fixed rated for any given rotation of the gear, but recalculate the rate for every rotation.

There is an inherent delay of 24 pulses before you start outputting at the new rate, but I doubt that this would impact your application.

Have a go at the code and report back.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.