# noobe having problems with math equation

It has been a wile since played with my arduino, trying to put a sketch together to control some engine timing devices. The problem I am having is I need to do some math that involves a decimal number. I am trying to convert frequency into degrees of rotation. What I have come up with is that Frequency * .000036 = degrees per microsecond. But I guess the arduino doesn't like decimal numbers? Is there any work around to achieve this calculation? Any help would be greatly appreciated.

Post your actual code. If you use the data type float correctly, decimals work fine.

Here is a piece of the code, the math part.

dwell_degrees_delay1..... is the amount of time the delay needs to be.
_pulse_frequency1.... is the frequency of the measured pulse
FREQ_DEGREE_CONV.... is the conversion it = .000036
dwell_delay_degrees1..... is a user defined value

What I am trying to do is read a varying frequency and delay a set amount of degrees no matter what the frequency is. Does this help?

``````dwell_degrees_delay1 = ((_pulse_frequency1 * FREQ_DEGREE_CONV) * dwell_delay_degrees1);
``````

why are you trying to multiply it by the user defined varriable of dwell_delay_degrees1? Please post your full code. Also, if FREQ_DEGREE_CONV is a decimal, what kind of varriable are you declaring it as?

Here is a useful post. You can re-arrange the equation to find time rather than degrees.

if dwell_delay_degrees1 is an integer of some sort, only integer math is performed, your equation will evaluate to a decimal if used with floating types.

Ok here is the full code, it was originally written by someone else to control a pulse motor, and worked by outputting a pulse that was a percentage of the input frequency, but I need it to output a pulse for a set amount of degrees.

`````` // ***********************************************************************************
// User controls.
// ***********************************************************************************
volatile float dwell_degrees1 = 30;        // Amount of degrees valve is on (1)
volatile float dwell_degrees2 = 30;        // Amount of degrees valve is on (2)
volatile float dwell_delay_degrees1 = 60;  //  Amount of degrees till TDC (1)
volatile float dwell_delay_degrees2 = 60;  //  Amount of degrees till TDC (2)
// ***********************************************************************************
// End of user controls.
// ***********************************************************************************

//#define DEBUG                            // Enable debug ouput - at cost/accuracy
//#define DEBUG_ANALOG_ONLY                // Enable debug ouput - analog only
//#define VARIABLE_HIGH                    // Dwell HIGH is percentage of input period

#define READ_ANALOG_DELAY1_DEGREES               // Allow setting of delay from Potentiometers
//#define READ_ANALOG_DWELL1_DEGREES               // Allow setting of dwell from Potentiometers

#define MAX_MISSED_PULSES 100              // Maximum number of miseed pulses before an
// error condition is flagged

//#define RESET_ON_MISSED_PULSES             // If missed pulses recur, then reboot

// ***********************************************************************************
// If using AVR Studio, remember to un-comment the line #define AVR_STUDIO, otherwise
// the Arduino IDE is assumed as the development environment.
//
// Command line parameters to upload to Arduino Duemilanove assuming 57600 baud rate:
//
// avrdude -p m328p -c avrisp -P com3 -b 57600 -F -U flash:w:freq_counter.hex
//
// Press RESET on the Arduino within 2 seconds of pressing ENTER!!!
//
// Note: The '.hex' file is located in a folder called 'default' which is created
// inside the project folder by AVR Studio. Substitute 'com3' with your own com port.
// ***********************************************************************************
//#define AVR_STUDIO
#ifdef AVR_STUDIO
#define F_CPU 16000000UL
#endif

//#include "WProgram.h"
#include <avr/wdt.h>
#include <SoftwareSerial.h>

#ifdef AVR_STUDIO
#if defined(DEBUG) || defined(DEBUG_ANALOG_ONLY)
//#include "./arduino/libraries/NewSoftSerial/NewSoftSerial.h"
NewSoftSerial mySerial(0, 1);
#define IOSERIAL mySerial
#endif
#else
#if defined(DEBUG) || defined(DEBUG_ANALOG_ONLY)
#define IOSERIAL Serial
#endif
#endif

#define FMULT  1024
#define FSHIFT 10
#define Freq_Degree  0.00036
// ***********************************************************************************
// Experimental...pulse level inversion section
// ***********************************************************************************
//#define INVERT_OUTPUT1                     // Invert output HIGH/LOW
//#define INVERT_OUTPUT2                     // Invert output HIGH/LOW

// ***********************************************************************************
// Forward declarations to keep AVR Studio happy. Arduino 'language' is less strict
// and as a consequence leads to some pretty bad habits to be developed by beginners.
// ***********************************************************************************
void setup(void);
void ISR_CHANGE_0(void);
void ISR_CHANGE_1(void);
unsigned long getTicksHigh1(void);
unsigned long getTicksLow1(void);
unsigned long getTicksHigh2(void);
unsigned long getTicksLow2(void);
unsigned long getPulseIn(int pin, boolean level);
void outputPulse1(void);
void outputPulse2(void);
void errorCheck(void);
void loop(void);

// ***********************************************************************************
// Experimental...pulse level inversion section
// ***********************************************************************************

#ifdef INVERT_OUTPUT1
#define OUT_HIGH1 LOW
#define OUT_LOW1  HIGH
#else
#define OUT_HIGH1 HIGH
#define OUT_LOW1  LOW
#endif

#ifdef INVERT_OUTPUT2
#define OUT_HIGH2 LOW
#define OUT_LOW2  HIGH
#else
#define OUT_HIGH2 HIGH
#define OUT_LOW2  LOW
#endif

// ***********************************************************************************
// These constants defines values expressed in microseconds. They are used to make
// small calibration adjustments of measured microseconds during the pulse capture
// phases in order to match the oscilloscope readings I get. Of course, my scope
// ***might*** be out of calibration but it is a Pico 200/100 and seems to be very
// accurate in everything else when I compare it with the readings from my Tektronix 475
// and that is ***not*** out of calibration. Nevertherless...experimental only!!!
// ***********************************************************************************

#define FREQ_DEGREE_CONV 0.00036
// ***********************************************************************************
// Minimal difference equates to get AVR Studio and Arduino 'IDE' to share code.
// ***********************************************************************************
#ifdef AVR_STUDIO
#define A0 54
#define A1 55
#define A2 56
#define A3 57
#define A4 58
#define A5 59
#define A6 60
#define A7 61
#endif

// ***********************************************************************************
// Pin definitions section
// ***********************************************************************************
int inputPin1 = 2;
int inputPin2 = 3;
int inputAPin1 = A0;
#endif
int inputAPin2 = A1;
#endif
int inputAPin3 = A2;
#endif
int inputAPin4 = A3;
#endif
int outputPin1 = 7;
int outputPin2 = 8;

// ***********************************************************************************
// Flags used for control and syncronization. This is the only 'running' coupling.
// ***********************************************************************************
volatile boolean Pout1 = false;    // Process control toggle (1)
volatile boolean Pout2 = false;    // Process control toggle (2)

// ***********************************************************************************
// These variables hold the measured time in microseconds for the HIGH and LOW level
// of the incoming pulses on pin 1. They are constantly updated in interrupt handler.
// ***********************************************************************************
volatile unsigned long __timer_ticks_high0 = 0;        // HIGH level microseconds (1)
volatile unsigned long __timer_ticks_low0 = 0;         // LOW level microseconds (1)
volatile boolean __got_pulse0 = false;                 // Pulse aquisition flag (1)
volatile unsigned long __pulse_start_time0 = 0;        // Pulse start microsecond (1)
volatile unsigned long __pulse_completion_time0 = 0;   // Pulse completion microsecond (1)
volatile unsigned long __iperiod0 = 0;                 // Pulse period microseconds (1)
volatile unsigned long __pulse_mark0 = 0;              // Time marking (input 1)
volatile unsigned long _pulse_frequency1 = 0;
volatile int __pulse_event0 = 0;
volatile int __pulse_count0 = 0;

// ***********************************************************************************
// These variables hold the measured time in microseconds for the HIGH and LOW level
// of the incoming pulses on pin 2. They are constantly updated in interrupt handler.
// ***********************************************************************************
volatile unsigned long __timer_ticks_high1 = 0;        // HIGH level microseconds (2)
volatile unsigned long __timer_ticks_low1 = 0;         // LOW level microseconds (2)
volatile boolean __got_pulse1 = false;                 // Pulse aquisition flag (2)
volatile unsigned long __pulse_start_time1 = 0;        // Pulse start microsecond (2)
volatile unsigned long __pulse_completion_time1 = 0;   // Pulse completion microsecond (2)
volatile unsigned long __iperiod1 = 0;                 // Pulse period microseconds (2)
volatile unsigned long __pulse_mark1 = 0;              // Time marking (input 2)
volatile unsigned long _pulse_frequency2 = 0;
volatile int __pulse_event1 = 0;
volatile int __pulse_count1 = 0;
``````

This is going to be in a few parts as the max allowed text here is part 2

``````// ***********************************************************************************
// These variables are used to hold the HIGH and LOW levels of the incoming pulses
// on input pin 1.
// ***********************************************************************************
volatile unsigned long pulseWidthHigh1 = 0;            // Intermediate pulse HIGH (1)
volatile unsigned long pulseWidthLow1 = 0;             // Intermediate pulse LOW (1)
volatile unsigned long pulsePeriod1 = 0;               // Intermediate pulse period (1)

// ***********************************************************************************
// These variables are used to hold the HIGH and LOW levels of the incoming pulses
// on input pin 2.
// ***********************************************************************************
volatile unsigned long pulseWidthHigh2 = 0;            // Intermediate pulse HIGH (2)
volatile unsigned long pulseWidthLow2 = 0;             // Intermediate pulse LOW (2)
volatile unsigned long pulsePeriod2 = 0;               // Intermediate pulse period (2)

// ***********************************************************************************
// Intermediate output pulse level durations section
// ***********************************************************************************
unsigned long dwell_degrees_high1 = 0;                         // Intermediate HIGH (input 1)
unsigned long dwell_degrees_low1 = 0;                          // Intermediate LOW (input 1)
unsigned long dwell_degrees_delay1 = 0;                        // Intermediate delay (input 1)
unsigned long dwell_degrees_high2 = 0;                         // Intermediate HIGH (input 2)
unsigned long dwell_degrees_low2 = 0;                          // Intermediate LOW (input 2)
unsigned long dwell_degrees_delay2 = 0;                        // Intermediate delay (input 2)

// ***********************************************************************************
// Output levels flag section
// ***********************************************************************************
boolean wait_preambleHigh1 = true;                     // Delay preamble flag (output 1)
boolean wait_degrees_delay1 = true;                            // Delay procesing flag (output 1)
boolean wait_degrees_high1 = true;                             // HIGH processing flag (output 1)
boolean wait_degrees_low1 = true;                              // LOW processing flag (output 1)
boolean wait_preambleHigh2 = true;                     // Delay preamble flag (output 2)
boolean wait_degrees_delay2 = true;                            // Delay processing flag (output 2)
boolean wait_degrees_high2 = true;                             // HIGH processing flag (output 2)
boolean wait_degrees_low2 = true;                              // LOW processing flag (output 2)

volatile unsigned long preambleHigh1 = 0;              // Preamble logic level (1)
volatile unsigned long preambleHigh2 = 0;              // Preamble logic level (2)

// ***********************************************************************************
// Local and global pulse time markers
// ***********************************************************************************
unsigned long time_mark = 0;                           // Global time marker

// ***********************************************************************************
// ***********************************************************************************
volatile float analog_degrees_delay1 = 0;  // Analog delay voltage reading (1)
volatile float old_analog_degrees_delay1 = 1;  // Analog delay voltage reading (1)
#endif
volatile float analog_degrees_delay2 = 0;  // Analog delay voltage reading (2)
volatile float old_analog_degrees_delay2 = 1;  // Analog delay voltage reading (2)
#endif
volatile float analog_degrees_dwell1 = 0;  // Analog dwell voltage reading (1)
volatile float old_analog_degrees_dwell1 = 1;  // Analog dwell voltage reading (1)
#endif
volatile float analog_degrees_dwell2 = 0;  // Analog dwell voltage reading (2)
volatile float old_analog_degrees_dwell2 = 1;  // Analog dwell voltage reading (2)
#endif

#endif

//volatile unsigned long uldwell_percentage1 = 50;       // ... (1)
//volatile unsigned long uldwell_percentage2 = 50;       // ... (2)
//volatile unsigned long uldwell_delay_percentage1 = 0;  // ...(1)
//volatile unsigned long uldwell_delay_percentage2 = 0;  // ...(2)

// ***********************************************************************************
// Reset method 1 using the jump vector. This restarts the program ***but*** register
// status remains unchanged across the reset.
// ***********************************************************************************
void(* softReset1) (void) = 0; //declare reset function @ address 0

// ***********************************************************************************
// void setup(void)
//
// Purpose:   Initialise variable and porogram running parameters
//
// Inputs:    none
//
// Returns:   nothing
// ***********************************************************************************
void setup(void)
{
Serial.begin(57600);
#if defined(DEBUG) || defined(DEBUG_ANALOG_ONLY) || defined(DEBUG2)
IOSERIAL.begin(57600);
#endif
pinMode(inputPin1, INPUT);        // Input pulses 1
pinMode(inputPin2, INPUT);        // Input pulses 2
digitalWrite(inputPin1, HIGH);    // Enable internal pullup for this pin (1)
digitalWrite(inputPin2, HIGH);    // Enable internal pullup for this pin (2)
pinMode(outputPin1, OUTPUT);
pinMode(outputPin2, OUTPUT);

// ************************************************
// Make sure the coupling flags are cleared.
// ************************************************
Pout1 = true;
Pout2 = true;

// ************************************************
// Pre-calculate dwell % to remove from loop
// ************************************************
//  dwell_degrees1 = (iperiod0 * 0.00036);              // Pre-calculate dwell percentage division (1)
//  dwell_degrees2 = (dwell_percentage2 / 100.0);              // Pre-calculate dwell percentage division (2)
//  dwell_delay_degrees1 = (dwell_delay_percentage1 / 100.0);  // Pre-calculate dwell delay percentage division (1)
//  dwell_delay_degrees2 = (dwell_delay_percentage2 / 100.0);  // Pre-calculate dwell delay percentage division (2)

//uldwell_percentage1 = (unsigned long)(dwell_percentage1 * FMULT);              // Pre-calculate dwell percentage division (1)
//uldwell_percentage2 = (unsigned long)(dwell_percentage2 * FMULT);              // Pre-calculate dwell percentage division (2)
//uldwell_delay_percentage1 = (unsigned long)(dwell_delay_percentage1 * FMULT);  // Pre-calculate dwell delay percentage division (1)
//uldwell_delay_percentage2 = (unsigned long)(dwell_delay_percentage2 * FMULT);  // Pre-calculate dwell delay percentage division (2)
``````

here is part 3

``````  // ************************************************
// Initialise variables for stream 0
// ************************************************
__timer_ticks_low0 = 0;          // Pulse LOW duration (input 1)
__timer_ticks_high0 = 0;         // Pulse HIGH duration (input 1)
__pulse_start_time0 = 0;         // Start of pulse in microseconds (input 1)
__pulse_completion_time0 = 0;    // End of pulse in microseconds (input 1a)
__iperiod0 = 0;                  // Pulse period (input 1)
__pulse_event0 = 0;
__pulse_count0 = 0;
_pulse_frequency1 = 0;
// ************************************************
// Initialise variables for stream 1
// ************************************************
__timer_ticks_low1 = 0;          // Pulse LOW duration (input 2)
__timer_ticks_high1 = 0;         // Pulse HIGH duration (input 2)
__pulse_start_time1 = 0;         // Start of pulse in microseconds (input 2)
__pulse_completion_time1 = 0;    // End of pulse in microseconds (input 2a)
__iperiod1 = 0;                  // Pulse period (input 2)
__pulse_event1 = 0;
__pulse_count1 = 0;
_pulse_frequency2 = 0;
// ************************************************
// Working variables
// ************************************************
dwell_degrees_high1 = 0;                 // Intermediate HIGH (input 1)
dwell_degrees_low1 = 0;                  // Intermediate LOW (input 1)
dwell_degrees_delay1 = 0;                // Intermediate delay (input 1)
dwell_degrees_high2 = 0;                 // Intermediate HIGH (input 2)
dwell_degrees_low2 = 0;                  // Intermediate LOW (input 2)
dwell_degrees_delay2 = 0;                // Intermediate delay (input 2)

wait_preambleHigh1 = true;       // Delay procesing flag (output 1)
wait_degrees_delay1 = true;              // Delay procesing flag (output 1)
wait_degrees_high1 = true;               // HIGH processing flag (output 1)
wait_degrees_low1 = true;                // LOW processing flag (output 1)
wait_preambleHigh2 = true;       // Delay procesing flag (output 1)
wait_degrees_delay2 = true;              // Delay processing flag (output 2)
wait_degrees_high2 = true;               // HIGH processing flag (output 2)
wait_degrees_low2 = true;                // LOW processing flag (output 2)

__pulse_mark0 = 0;               // Time marking (input 1)
__pulse_mark1 = 0;               // Time marker (input 2)

time_mark = 0;                   // Global time marker

// ************************************************
// Analog variable section. Hold potentiometer
// readings prior to convertion to percentage(s).
// ************************************************
analog_degrees_delay1 = 0;               // Analog delay voltage reading (output 1)
old_analog_degrees_delay1 = 1;               // Analog delay voltage reading (output 1)
#endif
analog_degrees_delay2 = 0;               // Analog delay voltage reading (output 2)
old_analog_degrees_delay2 = 1;               // Analog delay voltage reading (output 2)
#endif

analog_degrees_dwell1 = 0;               // Analog dwell voltage reading (output 1)
old_analog_degrees_dwell1 = 1;               // Analog dwell voltage reading (output 1)
#endif
analog_degrees_dwell2 = 0;               // Analog dwell voltage reading (output 2)
old_analog_degrees_dwell2 = 1;               // Analog dwell voltage reading (output 2)
#endif

// ************************************************
// Todo:
// ************************************************
attachInterrupt(0, ISR_CHANGE_0, CHANGE);  // Start first ISR (input 1)
attachInterrupt(1, ISR_CHANGE_1, CHANGE);  // Start second ISR (input 2)

#if defined(DEBUG) || defined(DEBUG_ANALOG_ONLY)
int x = 25;
while(x--) {
IOSERIAL.println();
}
IOSERIAL.println("Air Engine Controler");
IOSERIAL.println("Version 1.0");
IOSERIAL.println();
#endif
}
``````

part 4

``````  // ***********************************************************************************
// void ISR_CHANGE_0(void)
//
// Purpose:   Maintains a running duration of the incoming pulse periods. This is an
//            interrupt service routine and is triggered by the LEVEL CHANGE of the
//            incoming pulse on inputPin2.
//
//            Also, 'form' the outut pulse depending on the sum of the delay and dwell
//            durations exceeding the input pulse period. The intersection (difference)
//            is used to create a 'pre-delay' logic level and then trim the dwell & delay.
//
// Inputs:    None
//
// Returns:   Nothing
// ***********************************************************************************
void ISR_CHANGE_0(void)
{
return;
}

wait_degrees_delay1 = false;
wait_degrees_high1 = false;
wait_degrees_low1 = false;

__iperiod0 = (__pulse_completion_time0 - __pulse_start_time0);
__pulse_start_time0 = __pulse_completion_time0;
__pulse_completion_time0 = micros();

__pulse_mark0 = __pulse_completion_time0;
__got_pulse0 = true;
// *************************************************************
// 1. Calculate the pulse frequency
// *************************************************************

_pulse_frequency1 = (1000000 / __iperiod0 );
// *************************************************************
// 1. Calculate the degrees of 'dwell' and dealy.
// *************************************************************
dwell_degrees_high1 = ((_pulse_frequency1 * FREQ_DEGREE_CONV) * dwell_degrees1) * 2 ;
dwell_degrees_delay1 = ((_pulse_frequency1 * FREQ_DEGREE_CONV) * dwell_delay_degrees1);
// *************************************************************
// 2. Calculate the HIGH duration of the 'dwell' period.
// *************************************************************
__timer_ticks_high0 = dwell_degrees_high1;
// *************************************************************
// 3. Calculate the LOW duration of the 'dwell' period.
// *************************************************************
#ifdef VARIABLE_HIGH
__timer_ticks_low0 = __iperiod0 - dwell_high1;
#else
__timer_ticks_low0 = __timer_ticks_high0;
#endif

preambleHigh1 = (dwell_degrees_delay1 + dwell_degrees_high1);
if(preambleHigh1 >= __iperiod0) {
preambleHigh1 = preambleHigh1 - __iperiod0;
dwell_degrees_high1 = dwell_degrees_high1 - preambleHigh1;
dwell_degrees_delay1 = dwell_degrees_delay1 - preambleHigh1;
digitalWrite(outputPin1, OUT_HIGH1);
wait_preambleHigh1 = true;
} else {
wait_preambleHigh1 = false;
}

wait_degrees_delay1 = true;
wait_degrees_high1 = true;
wait_degrees_low1 = true;
}
``````

part 5

`````` // ***********************************************************************************
// void ISR_CHANGE_1(void)
//
// Purpose:   Maintains a running duration of the incoming pulse periods. This is an
//            interrupt service routine and is triggered by the LEVEL CHANGE of the
//            incoming pulse on inputPin1.
//
//            Also, 'form' the outut pulse depending on the sum of the delay and dwell
//            durations exceeding the input pulse period. The intersection (difference)
//            is used to create a 'pre-delay' logic level and then trim the dwell & delay.
//
// Inputs:    None
//
// Returns:   Nothing
// ***********************************************************************************
void ISR_CHANGE_1(void)
{
return;
}

wait_degrees_delay2 = false;
wait_degrees_high2 = false;
wait_degrees_low2 = false;

__iperiod1 = (__pulse_completion_time1 - __pulse_start_time1);
__pulse_start_time1 = __pulse_completion_time1;
__pulse_completion_time1 = micros();

__pulse_mark1 = __pulse_completion_time1;
__got_pulse1 = true;

// *************************************************************
// 1. Calculate the pulse frequency
// *************************************************************

_pulse_frequency2 = (1000000 / __iperiod1 );

// *************************************************************
// 1. Calculate the percentage 'dwell' and dealy.
// *************************************************************
dwell_degrees_high2 = ((_pulse_frequency2 * FREQ_DEGREE_CONV) * dwell_degrees2) * 2 ;
dwell_degrees_delay2 = ((_pulse_frequency2 * FREQ_DEGREE_CONV) * dwell_delay_degrees2);
// *************************************************************
// 2. Calculate the HIGH duration of the 'dwell' period.
// *************************************************************
__timer_ticks_high1 = dwell_degrees_high2;
// *************************************************************
// 3. Calculate the LOW duration of the 'dwell' period.
// *************************************************************
#ifdef VARIABLE_HIGH
__timer_ticks_low1 = __iperiod1 - dwell_high2;
#else
__timer_ticks_low1 = __timer_ticks_high1;
#endif

preambleHigh2 = (dwell_degrees_delay2 + dwell_degrees_high2);
if(preambleHigh2 >= __iperiod1) {
preambleHigh2 = preambleHigh2 - __iperiod1;
dwell_degrees_high2 = dwell_degrees_high2 - preambleHigh2;
dwell_degrees_delay2 = dwell_degrees_delay2 - preambleHigh2;
digitalWrite(outputPin2, OUT_HIGH2);
wait_preambleHigh2 = true;
} else {
wait_preambleHigh2 = false;
}

wait_degrees_delay2 = true;
wait_degrees_high2 = true;
wait_degrees_low2 = true;
}

// ***********************************************************************************
//
// Purpose:   Reports if a pulse detection is complete for a given pin.
//
// Inputs:    pin - integer 0 or 1
//
// Returns:   TRUE or FALSE
// ***********************************************************************************
{
switch(pin) {
case 0:
return(__got_pulse0);
break;
case 1:
return(__got_pulse1);
break;
default:
break;
}
return(false);
}

// ***********************************************************************************
// unsigned long getTicksHigh1(void)
//
// Purpose:   Return the last calculated duration in microseconds of the HIGH level of
//            a pulse period.
//
// Inputs:    None
//
// Returns:   Stored duration in microseconds of HIGH pulse level
// ***********************************************************************************
unsigned long getTicksHigh1(void)
{
return(__timer_ticks_high0);
}

// ***********************************************************************************
// unsigned long getTicksLow1(void)
//
// Purpose:   Return the last calculated duration in microseconds of the LOW level of
//            a pulse period.
//
// Inputs:    None
//
// Returns:   Stored duration in microseconds of LOW pulse level
// ***********************************************************************************
unsigned long getTicksLow1(void)
{
return(__timer_ticks_low0);
}

// ***********************************************************************************
// unsigned long getTicksHigh2(void)
//
// Purpose:   Return the last calculated duration in microseconds of the HIGH level of
//            a pulse period.
//
// Inputs:    None
//
// Returns:   Stored duration in microseconds of HIGH pulse level
// ***********************************************************************************
unsigned long getTicksHigh2(void)
{
return(__timer_ticks_high1);
}

// ***********************************************************************************
// unsigned long getTicksLow2(void)
//
// Purpose:   Return the last calculated duration in microseconds of the LOW level of
//            a pulse period.
//
// Inputs:    None
//
// Returns:   Stored duration in microseconds of LOW pulse level
// ***********************************************************************************
unsigned long getTicksLow2(void)
{
return(__timer_ticks_low1);
}

// ***********************************************************************************
// unsigned long getPulseIn(int pin, boolean level)
//
// Purpose:   Return the HIGH or LOW level duration in microseconds of the last pulse
//            period based on the input parameters.
//
// Inputs:    pin - 0 = pin 2, 1 = pin 3
//            level - 0 = HIGH, 1 = LOW
//
// Returns:   HIGH or LOW duration of pulse period
// ***********************************************************************************
unsigned long getPulseIn(int pin, boolean level)
{
switch(pin) {
case 0:
switch(level) {
case HIGH:
return(__timer_ticks_high0);
break;
case LOW:
return(__timer_ticks_low0);
break;
default:
break;
}
break;
case 1:
switch(level) {
case HIGH:
return(__timer_ticks_high1);
break;
case LOW:
return(__timer_ticks_low1);
break;
default:
break;
}
break;
default:
break;
}
return(LOW);
}
``````

part 6

`````` // ***********************************************************************************
// void outputPulse1(void)
//
// Purpose:   Output the different LEVELS of a pulse, including the preceding delay.
//            This routine also takes into account the logic level inversion in place.
//
// Inputs:    None
//
// Returns:   Nothing
// ***********************************************************************************
void outputPulse1(void)
{
if(wait_preambleHigh1) {
if(time_mark >= (__pulse_mark0 * FREQ_DEGREE_CONV)) {
digitalWrite(outputPin1, OUT_LOW1);       // non-inverted
__pulse_mark0 = time_mark;
wait_preambleHigh1 = false;
}
}
else if(wait_degrees_delay1) {
if(time_mark >= (__pulse_mark0 + dwell_degrees_delay1)) {
digitalWrite(outputPin1, OUT_HIGH1);       // non-inverted
__pulse_mark0 = time_mark;
wait_degrees_delay1 = false;
}
}
else if(wait_degrees_high1) {
if(time_mark >= (__pulse_mark0 + dwell_degrees_high1)) {
digitalWrite(outputPin1, OUT_LOW1);        // non-inverted
__pulse_mark0 = time_mark;
wait_degrees_high1 = false;
}
}
}

// ***********************************************************************************
// void outputPulse2(void)
//
// Purpose:   Output the different LEVELS of a pulse, including the preceding delay.
//            This routine also takes into account the logic level inversion in place.
//
// Inputs:    None
//
// Returns:   Nothing
// ***********************************************************************************
void outputPulse2(void)
{
if(wait_preambleHigh2) {
if(time_mark >= (__pulse_mark1 + preambleHigh2)) {
digitalWrite(outputPin2, OUT_LOW2);       // non-inverted
__pulse_mark1 = time_mark;
wait_preambleHigh2 = false;
}
}
else if(wait_degrees_delay2) {
if(time_mark >= (__pulse_mark1 + dwell_degrees_delay2)) {
digitalWrite(outputPin2, OUT_HIGH2);       // non-inverted
__pulse_mark1 = time_mark;
wait_degrees_delay2 = false;
}
}
else if(wait_degrees_high2) {
if(time_mark >= (__pulse_mark1 + dwell_degrees_high2)) {
digitalWrite(outputPin2, OUT_LOW2);        // non-inverted
__pulse_mark1 = time_mark;
wait_degrees_high2 = false;
}
}
}

// ***********************************************************************************
//
// Purpose:   To sample the voltage appearing on the analog input pins and convert the
//            read voltage(s) into a percentage in the range: 0V = 0% to 5V = 100%.
//
// Inputs:    None
//
// Returns:   Nothing
// ***********************************************************************************
{
if(analog_degrees_delay1 != old_analog_degrees_delay1) {
old_analog_degrees_delay1 = analog_degrees_delay1;
dwell_delay_degrees1 = analog_degrees_delay1 / 1000.0;
}
#endif
if(analog_degrees_delay2 != old_analog_degrees_delay2) {
old_analog_degrees_delay2 = analog_degrees_delay2;
dwell_delay_degrees2 = analog_degrees_delay2 / 1000.0;
}
#endif

if(analog_degrees_dwell1 != old_analog_degrees_dwell1) {
old_analog_degrees_dwell1 = analog_degrees_dwell1;
dwell_degrees1 = analog_degrees_dwell1 / 1000.0;
}
#endif
if(analog_degrees_dwell2 != old_analog_degrees_dwell2) {
old_analog_dwell2 = analog_degrees_dwell2;
dwell_degrees2 = analog_degrees_dwell2 / 1000.0;
}
#endif
}
#endif

// ***********************************************************************************
// void errorCheck(void)
//
// Purpose:   Perform error checking for missed pulses. If the number of missed pulses
//            or 'hung' pulses is greater than a predetermined limit - do something
//            about it because such a thing as increasing entropy will completely skew
//            the results FAST!
//
// Inputs:    None
//
// Returns:   Nothing
// ***********************************************************************************
void errorCheck(void)
{
static int error_count1 = 0;
static int error_count2 = 0;

// *************************************************************
// Stop interrupts
// *************************************************************
cli();

// *************************************************************
// Error check: missed pulse on input pin 1
// *************************************************************
if(__got_pulse0 && digitalRead(inputPin1) == HIGH) {
if((time_mark - __pulse_start_time0) > (__iperiod0 << 4)) {
error_count1++;
if(error_count1 > MAX_MISSED_PULSES) {
error_count1 = 0;
wait_degrees_delay1 = false;
wait_degrees_high1 = false;
Pout1 = false;
digitalWrite(outputPin1, LOW);
#ifdef RESET_ON_MISSED_PULSES
sei();
softReset1();
#endif
}
}
}

// *************************************************************
// Error check: missed pulse on input pin 2
// *************************************************************
if(__got_pulse1 && digitalRead(inputPin2) == HIGH) {
if((time_mark - __pulse_start_time1) > (__iperiod1 << 4)) {
error_count2++;
if(error_count2 > MAX_MISSED_PULSES) {
error_count2 = 0;
wait_degrees_delay2 = false;
wait_degrees_high2 = false;
Pout2 = false;
digitalWrite(outputPin2, LOW);
#ifdef RESET_ON_MISSED_PULSES
sei();
softReset1();
#endif
}
}
}

// *************************************************************
// Re-start interrupts
// *************************************************************
sei();
}
``````

part 7

``````// ***********************************************************************************
// void debug(void)
//
// Purpose:   Print debug information to the serial port
//
// Inputs:    None
//
// Returns:   Nothing
// ***********************************************************************************

#ifdef DEBUG
void debug(void)
{
#if defined(DEBUG)
unsigned long dwell_High1 = 0;
unsigned long dwell_High2 = 0;
unsigned long dwell_Low1 = 0;
unsigned long dwell_Low2 = 0;
float pulseFrequency1 = 0.0;
float pulseFrequency2 = 0.0;
#endif

// *************************************************************
// 6. Obtain duration in microseconds of pulse HIGH, LOW levels.
// *************************************************************
dwell_High1 = getPulseIn(0, HIGH);
dwell_Low1 = getPulseIn(0, LOW);
dwell_High2 = getPulseIn(1, HIGH);
dwell_Low2 = getPulseIn(1, LOW);

// *************************************************************
// 7. Calculate pulse period (HIGH + LOW).
//    F = 1/T, but T is in microseconds so...
//    F = (1/T) * 1000000
// *************************************************************
pulsePeriod1 = dwell_High1 + dwell_Low1; //pulseWidthHigh1 + pulseWidthLow1;
pulsePeriod2 = dwell_High2 + dwell_Low2; //pulseWidthHigh2 + pulseWidthLow2;
pulseFrequency1 = 1000000 / pulsePeriod1;
pulseFrequency2 = 1000000 / pulsePeriod2;
#endif
// *************************************************************
// 8. Output debug information. Note: enabled debug WILL affect the
//    overall efficiency of the program and should only be used for
//    reference purposes.
// *************************************************************
#if defined(DEBUG) || defined(DEBUG_ANALOG_ONLY)
static long scounter = 5001;

if(scounter >5000) {
scounter = 0;
#if !defined(DEBUG_ANALOG_ONLY)
// Output some debugging information...
IOSERIAL.print(pulseFrequency1, 0);
IOSERIAL.print(" Hz (out)");
IOSERIAL.print(", period = ");
IOSERIAL.print(pulsePeriod1, DEC);
IOSERIAL.print(", High = ");
//IOSERIAL.print(pulseWidthHigh1, DEC);
IOSERIAL.print(dwell_High1, DEC);
IOSERIAL.print(", Low = ");
//IOSERIAL.print(pulseWidthLow1, DEC);
IOSERIAL.print(dwell_Low1, DEC);
IOSERIAL.print(", dwell = ");
#ifdef VARIABLE_HIGH
IOSERIAL.print(dwell_High1, DEC);
#else
IOSERIAL.print(dwell_High1 << 1, DEC);
#endif
#endif
#if defined(DEBUG) && !defined(DEBUG_ANALOG_ONLY)
IOSERIAL.print(",");
#endif
#endif
#if defined(DEBUG_ANALOG_ONLY) || (defined(DEBUG) && !defined(DEBUG_ANALOG_ONLY))
IOSERIAL.print(" dwell1 = ");
IOSERIAL.print(dwell_percentage1 * 100, 0);
IOSERIAL.print("%");
#endif
IOSERIAL.print(",");
#endif
IOSERIAL.print(" delay1 = ");
IOSERIAL.print(dwell_delay_percentage1 * 100, 0);
IOSERIAL.print("%");
#endif
IOSERIAL.print(",");
#endif
IOSERIAL.print(" dwell2 = ");
IOSERIAL.print(dwell_percentage2 * 100, 0);
IOSERIAL.print("%");
#endif
IOSERIAL.print(",");
#endif
IOSERIAL.print(" delay2 = ");
IOSERIAL.print(dwell_delay_percentage2 * 100, 0);
IOSERIAL.print("%");
#endif
#endif
#ifdef VARIABLE_HIGH
IOSERIAL.print(" (variable HIGH)");
#endif
IOSERIAL.println(" ");
}
scounter++;
}
#endif

// ***********************************************************************************
// void loop(void)
//
// Purpose:   Main program loop. The work flow in this loop is as follows:
//
//            1. Read analog values and convert to percentages
//            2. Fetch the current time for use in the next section
//            3. See if any pulses are pending and if so, output the correct
//               levels depending how much time has elapsed
//            4. Error check: missed pulse on input pin 1
//            5. Obtain duration in microseconds of pulse HIGH, LOW levels.
//            6. Calculate pulse period (HIGH + LOW).
//               F = 1/T, but T is in microseconds so...
//               F = (1/T) * 1000000
//            7. Output debug information. Note: enabled debug WILL affect the
//               overall efficiency of the program and should only be used for
//               reference purposes.
//
// Inputs:    None
//
// Returns:   Nothing
// ***********************************************************************************
void loop(void)
{

Serial.print(" dwell1 degrees = ");
Serial.print(dwell_degrees1 * 100, 0);
Serial.print("^");

// *************************************************************
// Enable and give the pulse capture functions time to lock.
// *************************************************************
for(int x=0;x<10;x++) {
Pout1 = false;
Pout2 = false;
}

while(1) {
// *************************************************************
// 1. Read analog values and convert to percentages
// *************************************************************
#endif

// *************************************************************
// 2. Fetch the current time for use in the next section
// *************************************************************
time_mark = micros();

// *************************************************************
// 3. See if any pulses are pending and if so, output the correct
//    levels depending how much time has elapsed
// *************************************************************
outputPulse1();
outputPulse2();
``````

part 8

``````     // *************************************************************
// 4. Error check: missed pulse on input pin 1
// *************************************************************
//errorCheck();

#ifdef DEBUG
// *************************************************************
// 5. Obtain duration in microseconds of pulse HIGH, LOW levels.
// *************************************************************
dwell_High1 = getPulseIn(0, HIGH);
dwell_Low1 = getPulseIn(0, LOW);
dwell_High2 = getPulseIn(1, HIGH);
dwell_Low2 = getPulseIn(1, LOW);

// *************************************************************
// 6. Calculate pulse period (HIGH + LOW).
//    F = 1/T, but T is in microseconds so...
//    F = (1/T) * 1000000
// *************************************************************
pulsePeriod1 = dwell_High1 + dwell_Low1; //pulseWidthHigh1 + pulseWidthLow1;
pulsePeriod2 = dwell_High2 + dwell_Low2; //pulseWidthHigh2 + pulseWidthLow2;
pulseFrequency1 = 1000000 / pulsePeriod1;
pulseFrequency2 = 1000000 / pulsePeriod2;
#endif
// *************************************************************
// 7. Output debug information. Note: enabled debug WILL affect the
//    overall efficiency of the program and should only be used for
//    reference purposes.
// *************************************************************
#if defined(DEBUG) || defined(DEBUG_ANALOG_ONLY)
static long scounter = 5001;

if(scounter >5000) {
scounter = 0;
#if !defined(DEBUG_ANALOG_ONLY)
// Output some debugging information...
IOSERIAL.print(pulseFrequency1, 0);
IOSERIAL.print(" Hz (out)");
IOSERIAL.print(", period = ");
IOSERIAL.print(pulsePeriod1, DEC);
IOSERIAL.print(", High = ");
//IOSERIAL.print(pulseWidthHigh1, DEC);
IOSERIAL.print(dwell_High1, DEC);
IOSERIAL.print(", Low = ");
//IOSERIAL.print(pulseWidthLow1, DEC);
IOSERIAL.print(dwell_Low1, DEC);
IOSERIAL.print(", dwell = ");
#ifdef VARIABLE_HIGH
IOSERIAL.print(dwell_High1, DEC);
#else
IOSERIAL.print(dwell_High1 << 1, DEC);
#endif
#endif
#if defined(DEBUG) && !defined(DEBUG_ANALOG_ONLY)
IOSERIAL.print(",");
#endif
#endif
#if defined(DEBUG_ANALOG_ONLY) || (defined(DEBUG) && !defined(DEBUG_ANALOG_ONLY))
IOSERIAL.print(" dwell1 degrees = ");
IOSERIAL.print(dwell_degrees1 * 100, 0);
IOSERIAL.print("^");
#endif
IOSERIAL.print(",");
#endif
IOSERIAL.print(" delay1 degrees = ");
IOSERIAL.print(dwell_delay_degrees1 * 100, 0);
IOSERIAL.print("^");
#endif
IOSERIAL.print(",");
#endif
IOSERIAL.print(" dwell2 degrees = ");
IOSERIAL.print(dwell_degrees2 * 100, 0);
IOSERIAL.print("^");
#endif
IOSERIAL.print(",");
#endif
IOSERIAL.print(" delay2 degrees = ");
IOSERIAL.print(dwell_delay_degrees2 * 100, 0);
IOSERIAL.print("^"); y
#endif
#endif
#ifdef VARIABLE_HIGH
IOSERIAL.print(" (variable HIGH)");
#endif
IOSERIAL.println(" ");
}
scounter++;
#endif
}
}

// ***********************************************************************************
// int main(void)
//
// Purpose:   Traditional 'C' programs require a user supplied function called 'main'.
//            This function is conditionaly supplied here because the AVR Studio
//            environment follows the model of traditional 'C' programming while the
//            Arduino IDE - targeting beginner and non-professional developers - omits
//            this compiler requirement (but nevertheless provides it under the hood
//            so to speak). 'main()' is the actual entry point for the user program.
//
// Inputs:    None
//
// Returns:   0 (error code)
// ***********************************************************************************
#ifdef AVR_STUDIO
int main(void)
{
init();

setup();

while(1) {
loop();
}

return 0;
}
#endif
``````

Ok there is the whole sketch, sorry it had to be in so many pieces.

Haha, nice...
Which one one of 'em contains the code that was not working?
What was the values you were receiving from it? ( if available )
What where the values you were expecting from it?

Edit Foundit! Part 4., While I check it out, I think your problem is mixing data types, have a squiz at this
integral promotion: it doesn't have to be logical it's the law

Implicit type conversion
Implicit type conversion, also known as coercion, is an automatic type conversion by the compiler. Some languages allow, or even require, compilers to provide coercion.
In a mixed-type expression, data of one or more subtypes can be converted to a supertype as needed at runtime so that the program will run correctly. For example, the following is legal C language code:

``````double  d;
long    l;
int     i;

if (d > i)      d = i;
if (i > l)      l = i;
if (d == l)     d *= 2;
``````

Although d, l and i belong to different data types, they will be automatically converted to equal data types each time a comparison or assignment is executed. This behavior should be used with caution, as unintended consequences can arise. Data can be lost when floating-point representations are converted to integer representations as the fractional components of the floating-point values will be truncated (rounded towards zero). Conversely, converting from an integer representation to a floating-point one can also lose precision, since the floating-point type may be unable to represent the integer exactly (for example, float might be an IEEE 754 single precision type, which cannot represent the integer 16777217 exactly, while a 32-bit integer type can).

Your equation is mostly integers, the only floating point data you provide is
FREQ_DEGREE_CONV and
dwell_degrees1

it looks like this.

int = ((int * float) * float) * int;

The entire right-hand side is cast to an int for the assignment.
the ((int * float) * float) is cast to an int before that when it is multiplied by an int.

Try and floatify the equation and see if any different

``````dwell_degrees_high2 = (((1000000.0f / ( float )__iperiod1 ) * FREQ_DEGREE_CONV) * dwell_degrees2) * 2.0f ;
``````

If you are expecting a floating point at the result, wont happen due to dwell_degrees_high2 being an integer type.

Pyro, thanks for your help, I will try this in the morning and post results. Thanks again.