I've updated the code:
/*
Read square wave speed signal in on pin2 and output squarewave speed on pin4
*/
volatile uint32_t lastPulseTime = 0;
volatile uint32_t lastPulseWidth = 0;
uint32_t square_in = 0; //speed received
uint32_t square_out = 0; //speed to send
const int speed_pin = 2; //sqaure wave input from speed source
const int gear_pin = 3; //gear select input
const int speed_out = 4; //sqaure wave output
// variables for calculation
int gear; // current gear selected
// the setup routine runs once when you press reset:
uint32_t lastEdge = 0;
byte state = 0;
void setup() {
// initialize the digital pin as an output.
pinMode(speed_pin, INPUT);
pinMode(speed_out, OUTPUT);
pinMode(gear_pin, INPUT);
attachInterrupt(0, registerPulse, RISING);
}
// the loop routine runs over and over again forever:
void loop() {
//Sample data to test
square_in = 1000000UL / lastPulseWidth;
/*
read the square wave speed input from "speed_in" into variable "sqaure_in"
*/
gear = digitalRead(gear_pin);
if (gear == HIGH) { //ratio1 is selected
square_out = square_in * 201UL / 1138UL;
}//end of ratio1
else{ //ratio2 is selected
square_out = square_in * 420UL / 1777UL;
}//end of ratio2
/*
//output the variable "square_out" as square wave to "Speed_out"
*/
uint32_t outPulse = 500000UL / square_out; // get pulse length (not wave length)
uint32_t m = micros();
if (m - lastEdge >= outPulse) {
state = ! state;
digitalWrite(speed_out, state);
lastEdge = m;
}
}
void registerPulse() {
uint32_t cur = micros();
lastPulseWidth = cur - lastPulseTime;
lastPulseTime = cur;
}
Does this look right? is there anything which could be done more affectively?