From e836f8a545b86795546ae4004f4d387576187784 Mon Sep 17 00:00:00 2001 From: lonamle <114131069+lonamle@users.noreply.github.com> Date: Sat, 15 Apr 2023 19:26:38 -0700 Subject: [PATCH 1/8] Add files via upload added files for main.cpp and sensor driver code --- DAQ_FW/src/ISensorDriver.cpp | 24 +++++++++++++++++++++ DAQ_FW/src/main.cpp | 42 ++++++++++++++++++++++-------------- 2 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 DAQ_FW/src/ISensorDriver.cpp diff --git a/DAQ_FW/src/ISensorDriver.cpp b/DAQ_FW/src/ISensorDriver.cpp new file mode 100644 index 0000000..7dd9430 --- /dev/null +++ b/DAQ_FW/src/ISensorDriver.cpp @@ -0,0 +1,24 @@ +#include +#include + +uint16_t baseTemp(data, x) +{ + // for tempurature sensors - analog reading is directly proportional to temperature in deg-C + uint16_t temperature = data*x; //where x = proportionality constant, + return temperature; +}; + +uint16_t brakePressure(data) +{ + //for brake pressure sensor (MIPAN2XX500PSAAX) + uint16_t pressure = 625*(data-0.5); // in PSI, V_supply @ 25 deg-C = 5V (ratiometric) + return pressure; + +}; + +uint16_t tirePressure(data) +{ + //for coolant pressure sensor (116CP31-M04S2-50) + uint16_t pressure = 20*(data-0.5); + return pressure; +}; \ No newline at end of file diff --git a/DAQ_FW/src/main.cpp b/DAQ_FW/src/main.cpp index 39b8185..1cd2ab9 100644 --- a/DAQ_FW/src/main.cpp +++ b/DAQ_FW/src/main.cpp @@ -1,16 +1,26 @@ -#include "Logger.h" - -void setup() -{ - // put your setup code here, to run once: - Logger::Start(); - Logger::Notice("Setup"); -} - -void loop() -{ - // put your main code here, to run repeatedly: - Logger::Notice("Hello World"); - - delay(1000); -} +#include +#include + +int sr = 4; // pin number + +void setup() { + // put your setup code here, to run once: + pinMode(sr, OUTPUT); + Serial.begin(9600); + Serial.println("Connected"); +}; + +void loop() { + int data = analogRead(sr); + + float x=0.5; //temp sensor proportionality constant + + // example implementation of functions + // data = brakePressure(data); + + //display data + Serial.print("Sensor reading="); + Serial.println(data); + + delay(1000); + }; \ No newline at end of file From a3fb55ea48172cd90ddedeb06fdbb52a9be240a9 Mon Sep 17 00:00:00 2001 From: lonamle <114131069+lonamle@users.noreply.github.com> Date: Sat, 15 Apr 2023 19:27:50 -0700 Subject: [PATCH 2/8] Add files via upload --- DAQ_FW/include/ISensorDriver.h | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 DAQ_FW/include/ISensorDriver.h diff --git a/DAQ_FW/include/ISensorDriver.h b/DAQ_FW/include/ISensorDriver.h new file mode 100644 index 0000000..b7eab78 --- /dev/null +++ b/DAQ_FW/include/ISensorDriver.h @@ -0,0 +1,9 @@ +#include + +uint16_t baseTemp(); + + +uint16_t brakePressure(); + + +uint16_t tirePressure(); From b27d2446734c9ad00d82d7235279161d9345c8f1 Mon Sep 17 00:00:00 2001 From: lonamle <114131069+lonamle@users.noreply.github.com> Date: Thu, 15 Jun 2023 18:58:40 -0700 Subject: [PATCH 3/8] Add files via upload using interrupt to get wheel speed data from IR sensor --- main.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 main.cpp diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..b3820d8 --- /dev/null +++ b/main.cpp @@ -0,0 +1,87 @@ +#include +#include + +#define temp_PIN 4 // pin numbers +#define brakePressure_PIN 5 +#define coolantPressure_PIN 6 + +#define wheelSpeed_PIN 14 + +#define tempConst 5 // adjustable temperature proportionality constant for testing + +uint16_t wheelPulses=120; // set at random number for testing + +void IRAM_ATTR ISR(){ // interrupt service routine + wheelPulses ++; +} + +void setup() { + // put your setup code here, to run once: + /*pinMode(temp_PIN, OUTPUT); + pinMode(brakePressure_PIN, OUTPUT); + pinMode(coolantPressure_PIN, OUTPUT); */ + pinMode(wheelSpeed_PIN, OUTPUT); + + // attach interrupt that adds to pulse count when pin goes from HIGH to LOW + attachInterrupt(wheelSpeed_PIN, ISR, FALLING); + + Serial.begin(9600); + Serial.println("Connected"); +}; + +void loop() { + //------------- functions for temperature and pressure sensors ------------// + + //int tempData = analogRead(temp_PIN); + //int brakePressureData = analogRead(brakePressure_PIN); + //int tirePressureData = analogRead(coolantPressure_PIN); + + // example implementation of functions + // data = brakePressure(data); + + // for tempurature sensors - analog reading is directly proportional to temperature in deg-C + //uint16_t temperature = tempData*tempConst; + + //for brake pressure sensor (MIPAN2XX500PSAAX) + //uint16_t brakePressure = 625*(brakePressureData-0.5); // in PSI, V_supply @ 25 deg-C = 5V (ratiometric) //display data + + //for coolant pressure sensor (116CP31-M04S2-50) + //uint16_t tirePressure = 20*(tirePressureData-0.5); + + // for wheel speed sensor + //wheelPulses = 0; // start at 0 + + //Serial.print("Temperature reading= "); + //Serial.println(temperature); + + //Serial.print("Brake pressure reading= "); + //Serial.println(brakePressure); + + //Serial.print("Tire pressure reading= "); + //Serial.println(tirePressure); + + //-------------- wheel speed interrupt data --------------// + + delay(1000); // interrupt detects pulses over 1000ms + uint16_t wheelRPM = wheelPulses/20*60; // 20 pulses from wheel speed sensor corresponds to 1 revolution + + Serial.print("Wheel speed (RPM)= "); + Serial.println(wheelRPM); + + //-------------- wheel speed sensor testing --------------// + + int wheelSpeedData = analogRead(wheelSpeed_PIN); + + + if (wheelSpeedData == 1){ + Serial.println("Unblocked"); //test + }; + + if (wheelSpeedData==0){ + Serial.println("Blocked"); //test + }; + + //Serial.println(wheelPulses); + + }; + From d77275da8c8d825bab4e731ec62cb94b9db46aee Mon Sep 17 00:00:00 2001 From: lonamle <114131069+lonamle@users.noreply.github.com> Date: Thu, 14 Sep 2023 20:25:32 -0700 Subject: [PATCH 4/8] Add files via upload working code for 1 sensor, duplicated to work with 4 sensors but not yet tested --- main.cpp | 171 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 121 insertions(+), 50 deletions(-) diff --git a/main.cpp b/main.cpp index b3820d8..e278d37 100644 --- a/main.cpp +++ b/main.cpp @@ -1,87 +1,158 @@ #include #include -#define temp_PIN 4 // pin numbers -#define brakePressure_PIN 5 -#define coolantPressure_PIN 6 - -#define wheelSpeed_PIN 14 +#define frontLeft_WSPIN 14 +#define frontRight_WSPIN 16 +#define backLeft_WSPIN 18 +#define backRight_WSPIN 20 + +int volatile WP1=0; // set at random number for testing +int volatile WP2=0; // set at random number for testing +int volatile WP3=0; // set at random number for testing +int volatile WP4=0; // set at random number for testing + +int volatile irFlag1 = 0; +int volatile irFlag2 = 0; +int volatile irFlag3 = 0; +int volatile irFlag4 = 0; + +void IRAM_ATTR ISR1(){ // interrupt service routine + irFlag1 = 1; + WP1++; +} -#define tempConst 5 // adjustable temperature proportionality constant for testing +void IRAM_ATTR ISR2(){ // interrupt service routine + irFlag2 = 1; + WP2++; +} -uint16_t wheelPulses=120; // set at random number for testing +void IRAM_ATTR ISR3(){ // interrupt service routine + irFlag3 = 1; + WP3++; +} -void IRAM_ATTR ISR(){ // interrupt service routine - wheelPulses ++; +void IRAM_ATTR ISR4(){ // interrupt service routine + irFlag4 = 1; + WP4++; } +void interruptReset1(){ + detachInterrupt(frontLeft_WSPIN); + + irFlag1 = 0; + WP1= 0; + + attachInterrupt(frontLeft_WSPIN, ISR1, FALLING); +}; + +void interruptReset2(){ + detachInterrupt(frontRight_WSPIN); + + irFlag2 = 0; + WP2= 0; + + attachInterrupt(frontRight_WSPIN, ISR2, FALLING); +}; + +void interruptReset3(){ + detachInterrupt(backLeft_WSPIN); + + irFlag3 = 0; + WP3= 0; + + attachInterrupt(backLeft_WSPIN, ISR3, FALLING); +}; + +void interruptReset4(){ + detachInterrupt(backRight_WSPIN); + + irFlag4 = 0; + WP4= 0; + + attachInterrupt(backRight_WSPIN, ISR4, FALLING); +}; + void setup() { - // put your setup code here, to run once: - /*pinMode(temp_PIN, OUTPUT); - pinMode(brakePressure_PIN, OUTPUT); - pinMode(coolantPressure_PIN, OUTPUT); */ - pinMode(wheelSpeed_PIN, OUTPUT); + pinMode(frontRight_WSPIN, INPUT); // attach interrupt that adds to pulse count when pin goes from HIGH to LOW - attachInterrupt(wheelSpeed_PIN, ISR, FALLING); + attachInterrupt(frontLeft_WSPIN, ISR1, FALLING); + attachInterrupt(frontRight_WSPIN, ISR2, FALLING); + attachInterrupt(backLeft_WSPIN, ISR3, FALLING); + attachInterrupt(backRight_WSPIN, ISR4, FALLING); + Serial.begin(9600); Serial.println("Connected"); + + }; void loop() { - //------------- functions for temperature and pressure sensors ------------// + //-------------- wheel speed interrupt data --------------// + if(irFlag1){ + delay(1000); // interrupt detects pulses over 1000ms + + int RPM1 = WP1/49*60; // 20 pulses from wheel speed sensor corresponds to 1 revolution + + Serial.println(WP1); + Serial.print("Wheel 1 Speed (RPM)= "); + Serial.println(RPM1); - //int tempData = analogRead(temp_PIN); - //int brakePressureData = analogRead(brakePressure_PIN); - //int tirePressureData = analogRead(coolantPressure_PIN); - // example implementation of functions - // data = brakePressure(data); + interruptReset1(); + }; - // for tempurature sensors - analog reading is directly proportional to temperature in deg-C - //uint16_t temperature = tempData*tempConst; + if(irFlag1){ + delay(1000); // interrupt detects pulses over 1000ms - //for brake pressure sensor (MIPAN2XX500PSAAX) - //uint16_t brakePressure = 625*(brakePressureData-0.5); // in PSI, V_supply @ 25 deg-C = 5V (ratiometric) //display data + int RPM1 = WP1/49*60; // 20 pulses from wheel speed sensor corresponds to 1 revolution + + Serial.println(WP1); + Serial.print("Wheel 1 Speed (RPM)= "); + Serial.println(RPM1); - //for coolant pressure sensor (116CP31-M04S2-50) - //uint16_t tirePressure = 20*(tirePressureData-0.5); - // for wheel speed sensor - //wheelPulses = 0; // start at 0 + interruptReset1(); + }; - //Serial.print("Temperature reading= "); - //Serial.println(temperature); + if(irFlag2){ + delay(1000); // interrupt detects pulses over 1000ms - //Serial.print("Brake pressure reading= "); - //Serial.println(brakePressure); + int RPM2 = WP2/49*60; // 20 pulses from wheel speed sensor corresponds to 1 revolution - //Serial.print("Tire pressure reading= "); - //Serial.println(tirePressure); + Serial.println(WP2); + Serial.print("Wheel 2 Speed (RPM)= "); + Serial.println(RPM2); - //-------------- wheel speed interrupt data --------------// - delay(1000); // interrupt detects pulses over 1000ms - uint16_t wheelRPM = wheelPulses/20*60; // 20 pulses from wheel speed sensor corresponds to 1 revolution + interruptReset2(); + }; - Serial.print("Wheel speed (RPM)= "); - Serial.println(wheelRPM); + if(irFlag3){ + delay(1000); // interrupt detects pulses over 1000ms - //-------------- wheel speed sensor testing --------------// + int RPM3 = WP1/49*60; // 20 pulses from wheel speed sensor corresponds to 1 revolution + + Serial.println(WP3); + Serial.print("Wheel 3 Speed (RPM)= "); + Serial.println(RPM3); - int wheelSpeedData = analogRead(wheelSpeed_PIN); - - if (wheelSpeedData == 1){ - Serial.println("Unblocked"); //test - }; - - if (wheelSpeedData==0){ - Serial.println("Blocked"); //test + interruptReset1(); }; - //Serial.println(wheelPulses); + if(irFlag4){ + delay(1000); // interrupt detects pulses over 1000ms + + int RPM4 = WP4/49*60; // 20 pulses from wheel speed sensor corresponds to 1 revolution + + Serial.println(WP4); + Serial.print("Wheel 4 Speed (RPM)= "); + Serial.println(RPM4); + + interruptReset4(); }; +}; \ No newline at end of file From 8d0737a0959d1de998b164dcdb5fc285c0ed2272 Mon Sep 17 00:00:00 2001 From: lonamle <114131069+lonamle@users.noreply.github.com> Date: Thu, 23 Nov 2023 12:18:14 -0800 Subject: [PATCH 5/8] Add files via upload working code for 4 sensors --- DAQ_FW/src/main.cpp | 132 ++++++++++++++++++++++++++++++++++---- DAQ_FW/src/wheelSpeed.cpp | 18 ++++++ DAQ_FW/src/wheelSpeed.h | 9 +++ 3 files changed, 145 insertions(+), 14 deletions(-) create mode 100644 DAQ_FW/src/wheelSpeed.cpp create mode 100644 DAQ_FW/src/wheelSpeed.h diff --git a/DAQ_FW/src/main.cpp b/DAQ_FW/src/main.cpp index 1cd2ab9..74a0584 100644 --- a/DAQ_FW/src/main.cpp +++ b/DAQ_FW/src/main.cpp @@ -1,26 +1,130 @@ #include -#include +#include +#include + +// define sensor pins + +#define frontLeft_WSPIN 14 // wheel #1 +#define frontRight_WSPIN 16 // wheel #2 +#define backLeft_WSPIN 18 // wheel #3 +#define backRight_WSPIN 19 // wheel #4 + +// hardware timer pointer +hw_timer_t * timer = NULL; + +// define variables for counting + +int volatile WP1=0; +int volatile WP2=0; +int volatile WP3=0; +int volatile WP4=0; + +int volatile timerCounter = 0; + +// interrupt service routines: count interrupts + +void IRAM_ATTR ISR1(){ WP1++;} + +void IRAM_ATTR ISR2(){ WP2++;} + +void IRAM_ATTR ISR3(){ WP3++;} + +void IRAM_ATTR ISR4(){ WP4++;} + + +// interrupt reset functions: detach and reset interrupts after each period + +void interruptReset1(){ + detachInterrupt(frontLeft_WSPIN); + WP1= 0; + attachInterrupt(frontLeft_WSPIN, ISR1, FALLING); +} + +void interruptReset2(){ + detachInterrupt(frontRight_WSPIN); + WP2= 0; + attachInterrupt(frontRight_WSPIN, ISR2, FALLING); +} + +void interruptReset3(){ + detachInterrupt(backLeft_WSPIN); + WP3= 0; + attachInterrupt(backLeft_WSPIN, ISR3, FALLING); +} + +void interruptReset4(){ + detachInterrupt(backRight_WSPIN); + WP4= 0; + attachInterrupt(backRight_WSPIN, ISR4, FALLING); +} + + +// timer interrupt service routine + +void IRAM_ATTR onTimer(){ timerCounter ++;} -int sr = 4; // pin number void setup() { - // put your setup code here, to run once: - pinMode(sr, OUTPUT); + Serial.begin(9600); Serial.println("Connected"); -}; + + pinMode(frontRight_WSPIN, INPUT); + pinMode(frontLeft_WSPIN, INPUT); + pinMode(backLeft_WSPIN, INPUT); + pinMode(backRight_WSPIN, INPUT); + + // attach interrupt that adds to pulse count when pin goes from HIGH to LOW + + attachInterrupt(frontLeft_WSPIN, ISR1, FALLING); + attachInterrupt(frontRight_WSPIN, ISR2, FALLING); + attachInterrupt(backLeft_WSPIN, ISR3, FALLING); + attachInterrupt(backRight_WSPIN, ISR4, FALLING); + + // begin timer + + timer = timerBegin(0, 80, true); + + timerAttachInterrupt(timer, &onTimer, true); // attach timer interrupt + timerAlarmWrite(timer, 1000000, true); // 1 second interrupt period + timerAlarmEnable(timer); // enable timer interrupt +} + + +// void wheelSpeedDisplay(int volatile wheelPulses, int wheelNumber){ + +// // calculate RPM from wheel pulse count +// int RPM = wheelPulses/49*60; // subject to change based on tire + +// // print results +// Serial.print("Wheel "); +// Serial.print(wheelNumber); +// Serial.print(" RPM = "); +// Serial.println(RPM); + +// // print wheel pulse count for testing purposes +// Serial.print(wheelPulses); +// } + void loop() { - int data = analogRead(sr); + + // after 1 second, timer counter equals 1 + // when timerCounter equals 1, compute wheel speed using wheel pulse values + + if (timerCounter > 0){ + timerCounter --; - float x=0.5; //temp sensor proportionality constant + wheelSpeedDisplay(WP1, 1); + interruptReset1(); - // example implementation of functions - // data = brakePressure(data); + wheelSpeedDisplay(WP2, 2); + interruptReset2(); - //display data - Serial.print("Sensor reading="); - Serial.println(data); + wheelSpeedDisplay(WP3, 3); + interruptReset3(); - delay(1000); - }; \ No newline at end of file + wheelSpeedDisplay(WP4, 4); + interruptReset4(); + }; +} \ No newline at end of file diff --git a/DAQ_FW/src/wheelSpeed.cpp b/DAQ_FW/src/wheelSpeed.cpp new file mode 100644 index 0000000..d458070 --- /dev/null +++ b/DAQ_FW/src/wheelSpeed.cpp @@ -0,0 +1,18 @@ +#include +#include +#include + +void wheelSpeedDisplay(int volatile wheelPulses, int wheelNumber){ + + // calculate RPM from wheel pulse count + int RPM = wheelPulses/49*60; // subject to change based on tire + + // print results + Serial.print("Wheel "); + Serial.print(wheelNumber); + Serial.print(" RPM = "); + Serial.println(RPM); + + // print wheel pulse count for testing purposes + Serial.print(wheelPulses); +} \ No newline at end of file diff --git a/DAQ_FW/src/wheelSpeed.h b/DAQ_FW/src/wheelSpeed.h new file mode 100644 index 0000000..4d22e26 --- /dev/null +++ b/DAQ_FW/src/wheelSpeed.h @@ -0,0 +1,9 @@ +#ifndef WHEELSPEED_H +#define WHEELSPEED_H + +#include +#include + +void wheelSpeedDisplay(int volatile wheelPulses, int wheelNumber); + +#endif \ No newline at end of file From f751d8f37120a6cfbb729cd9e9ac47d161d7dd3c Mon Sep 17 00:00:00 2001 From: lonamle <114131069+lonamle@users.noreply.github.com> Date: Thu, 23 Nov 2023 12:19:36 -0800 Subject: [PATCH 6/8] Add files via upload timer library --- DAQ_FW/lib/TimerOne.cpp | 209 ++++++++++++++++++++++++++++++++++++++++ DAQ_FW/lib/TimerOne.h | 70 ++++++++++++++ 2 files changed, 279 insertions(+) create mode 100644 DAQ_FW/lib/TimerOne.cpp create mode 100644 DAQ_FW/lib/TimerOne.h diff --git a/DAQ_FW/lib/TimerOne.cpp b/DAQ_FW/lib/TimerOne.cpp new file mode 100644 index 0000000..efede8d --- /dev/null +++ b/DAQ_FW/lib/TimerOne.cpp @@ -0,0 +1,209 @@ +/* + * Interrupt and PWM utilities for 16 bit Timer1 on ATmega168/328 + * Original code by Jesse Tane for http://labs.ideo.com August 2008 + * Modified March 2009 by Jérôme Despatis and Jesse Tane for ATmega328 support + * Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop + * Modified June 2011 by Lex Talionis to add a function to read the timer + * Modified Oct 2011 by Andrew Richards to avoid certain problems: + * - Add (long) assignments and casts to TimerOne::read() to ensure calculations involving tmp, ICR1 and TCNT1 aren't truncated + * - Ensure 16 bit registers accesses are atomic - run with interrupts disabled when accessing + * - Remove global enable of interrupts (sei())- could be running within an interrupt routine) + * - Disable interrupts whilst TCTN1 == 0. Datasheet vague on this, but experiment shows that overflow interrupt + * flag gets set whilst TCNT1 == 0, resulting in a phantom interrupt. Could just set to 1, but gets inaccurate + * at very short durations + * - startBottom() added to start counter at 0 and handle all interrupt enabling. + * - start() amended to enable interrupts + * - restart() amended to point at startBottom() + * Modiied 7:26 PM Sunday, October 09, 2011 by Lex Talionis + * - renamed start() to resume() to reflect it's actual role + * - renamed startBottom() to start(). This breaks some old code that expects start to continue counting where it left off + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * See Google Code project http://code.google.com/p/arduino-timerone/ for latest + */ +#ifndef TIMERONE_cpp +#define TIMERONE_cpp + +#include "TimerOne.h" + +TimerOne Timer1; // preinstatiate + +ISR(TIMER1_OVF_vect) // interrupt service routine that wraps a user defined function supplied by attachInterrupt +{ + Timer1.isrCallback(); +} + + +void TimerOne::initialize(long microseconds) +{ + TCCR1A = 0; // clear control register A + TCCR1B = _BV(WGM13); // set mode 8: phase and frequency correct pwm, stop the timer + setPeriod(microseconds); +} + + +void TimerOne::setPeriod(long microseconds) // AR modified for atomic access +{ + + long cycles = (F_CPU / 2000000) * microseconds; // the counter runs backwards after TOP, interrupt is at BOTTOM so divide microseconds by 2 + if(cycles < RESOLUTION) clockSelectBits = _BV(CS10); // no prescale, full xtal + else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11); // prescale by /8 + else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11) | _BV(CS10); // prescale by /64 + else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12); // prescale by /256 + else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12) | _BV(CS10); // prescale by /1024 + else cycles = RESOLUTION - 1, clockSelectBits = _BV(CS12) | _BV(CS10); // request was out of bounds, set as maximum + + oldSREG = SREG; + cli(); // Disable interrupts for 16 bit register access + ICR1 = pwmPeriod = cycles; // ICR1 is TOP in p & f correct pwm mode + SREG = oldSREG; + + TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12)); + TCCR1B |= clockSelectBits; // reset clock select register, and starts the clock +} + +void TimerOne::setPwmDuty(char pin, int duty) +{ + unsigned long dutyCycle = pwmPeriod; + + dutyCycle *= duty; + dutyCycle >>= 10; + + oldSREG = SREG; + cli(); + if(pin == 1 || pin == 9) OCR1A = dutyCycle; + else if(pin == 2 || pin == 10) OCR1B = dutyCycle; + SREG = oldSREG; +} + +void TimerOne::pwm(char pin, int duty, long microseconds) // expects duty cycle to be 10 bit (1024) +{ + if(microseconds > 0) setPeriod(microseconds); + if(pin == 1 || pin == 9) { + DDRB |= _BV(PORTB1); // sets data direction register for pwm output pin + TCCR1A |= _BV(COM1A1); // activates the output pin + } + else if(pin == 2 || pin == 10) { + DDRB |= _BV(PORTB2); + TCCR1A |= _BV(COM1B1); + } + setPwmDuty(pin, duty); + resume(); // Lex - make sure the clock is running. We don't want to restart the count, in case we are starting the second WGM + // and the first one is in the middle of a cycle +} + +void TimerOne::disablePwm(char pin) +{ + if(pin == 1 || pin == 9) TCCR1A &= ~_BV(COM1A1); // clear the bit that enables pwm on PB1 + else if(pin == 2 || pin == 10) TCCR1A &= ~_BV(COM1B1); // clear the bit that enables pwm on PB2 +} + +void TimerOne::attachInterrupt(void (*isr)(), long microseconds) +{ + if(microseconds > 0) setPeriod(microseconds); + isrCallback = isr; // register the user's callback with the real ISR + TIMSK1 = _BV(TOIE1); // sets the timer overflow interrupt enable bit + // might be running with interrupts disabled (eg inside an ISR), so don't touch the global state +// sei(); + resume(); +} + +void TimerOne::detachInterrupt() +{ + TIMSK1 &= ~_BV(TOIE1); // clears the timer overflow interrupt enable bit + // timer continues to count without calling the isr +} + +void TimerOne::resume() // AR suggested +{ + TCCR1B |= clockSelectBits; +} + +void TimerOne::restart() // Depricated - Public interface to start at zero - Lex 10/9/2011 +{ + start(); +} + +void TimerOne::start() // AR addition, renamed by Lex to reflect it's actual role +{ + unsigned int tcnt1; + + TIMSK1 &= ~_BV(TOIE1); // AR added + GTCCR |= _BV(PSRSYNC); // AR added - reset prescaler (NB: shared with all 16 bit timers); + + oldSREG = SREG; // AR - save status register + cli(); // AR - Disable interrupts + TCNT1 = 0; + SREG = oldSREG; // AR - Restore status register + resume(); + do { // Nothing -- wait until timer moved on from zero - otherwise get a phantom interrupt + oldSREG = SREG; + cli(); + tcnt1 = TCNT1; + SREG = oldSREG; + } while (tcnt1==0); + +// TIFR1 = 0xff; // AR - Clear interrupt flags +// TIMSK1 = _BV(TOIE1); // sets the timer overflow interrupt enable bit +} + +void TimerOne::stop() +{ + TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12)); // clears all clock selects bits +} + +unsigned long TimerOne::read() //returns the value of the timer in microseconds +{ //rember! phase and freq correct mode counts up to then down again + unsigned long tmp; // AR amended to hold more than 65536 (could be nearly double this) + unsigned int tcnt1; // AR added + + oldSREG= SREG; + cli(); + tmp=TCNT1; + SREG = oldSREG; + + char scale=0; + switch (clockSelectBits) + { + case 1:// no prescalse + scale=0; + break; + case 2:// x8 prescale + scale=3; + break; + case 3:// x64 + scale=6; + break; + case 4:// x256 + scale=8; + break; + case 5:// x1024 + scale=10; + break; + } + + do { // Nothing -- max delay here is ~1023 cycles. AR modified + oldSREG = SREG; + cli(); + tcnt1 = TCNT1; + SREG = oldSREG; + } while (tcnt1==tmp); //if the timer has not ticked yet + + //if we are counting down add the top value to how far we have counted down + tmp = ( (tcnt1>tmp) ? (tmp) : (long)(ICR1-tcnt1)+(long)ICR1 ); // AR amended to add casts and reuse previous TCNT1 + return ((tmp*1000L)/(F_CPU /1000L))<. + * + * See Google Code project http://code.google.com/p/arduino-timerone/ for latest + */ +#ifndef TIMERONE_h +#define TIMERONE_h + +#include +#include + +#define RESOLUTION 65536 // Timer1 is 16 bit + +class TimerOne +{ + public: + + // properties + unsigned int pwmPeriod; + unsigned char clockSelectBits; + char oldSREG; // To hold Status Register while ints disabled + + // methods + void initialize(long microseconds=1000000); + void start(); + void stop(); + void restart(); + void resume(); + unsigned long read(); + void pwm(char pin, int duty, long microseconds=-1); + void disablePwm(char pin); + void attachInterrupt(void (*isr)(), long microseconds=-1); + void detachInterrupt(); + void setPeriod(long microseconds); + void setPwmDuty(char pin, int duty); + void (*isrCallback)(); +}; + +extern TimerOne Timer1; +#endif \ No newline at end of file From 975525115440408751471cc0d08d94de97eab9ef Mon Sep 17 00:00:00 2001 From: "LONA-LAPTOP\\lonam" Date: Sun, 21 Jan 2024 14:51:32 -0800 Subject: [PATCH 7/8] updated RPM calculation to format as float --- DAQ_FW/src/wheelSpeed.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DAQ_FW/src/wheelSpeed.cpp b/DAQ_FW/src/wheelSpeed.cpp index d458070..f315966 100644 --- a/DAQ_FW/src/wheelSpeed.cpp +++ b/DAQ_FW/src/wheelSpeed.cpp @@ -5,7 +5,7 @@ void wheelSpeedDisplay(int volatile wheelPulses, int wheelNumber){ // calculate RPM from wheel pulse count - int RPM = wheelPulses/49*60; // subject to change based on tire + int RPM = (wheelPulses/49.0)*60; // subject to change based on tire // print results Serial.print("Wheel "); @@ -14,5 +14,5 @@ void wheelSpeedDisplay(int volatile wheelPulses, int wheelNumber){ Serial.println(RPM); // print wheel pulse count for testing purposes - Serial.print(wheelPulses); + //Serial.print(wheelPulses); } \ No newline at end of file From 8730b19f4139b7740f365e8a1428039c1d45071f Mon Sep 17 00:00:00 2001 From: Lona Le Date: Thu, 7 Mar 2024 13:40:28 -0800 Subject: [PATCH 8/8] updated to calculate and output velocity value --- DAQ_FW/src/main.cpp | 12 +++++------- DAQ_FW/src/wheelSpeed.cpp | 31 ++++++++++++++++++++++++------- DAQ_FW/src/wheelSpeed.h | 2 +- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/DAQ_FW/src/main.cpp b/DAQ_FW/src/main.cpp index 74a0584..ec266dd 100644 --- a/DAQ_FW/src/main.cpp +++ b/DAQ_FW/src/main.cpp @@ -115,16 +115,14 @@ void loop() { if (timerCounter > 0){ timerCounter --; - wheelSpeedDisplay(WP1, 1); - interruptReset1(); + wheelSpeedDisplay(WP1, WP2, WP3, WP4); // prints velocity based on average wheel pulse counts - wheelSpeedDisplay(WP2, 2); - interruptReset2(); - wheelSpeedDisplay(WP3, 3); + // detach/reattach interrupts + + interruptReset1(); + interruptReset2(); interruptReset3(); - - wheelSpeedDisplay(WP4, 4); interruptReset4(); }; } \ No newline at end of file diff --git a/DAQ_FW/src/wheelSpeed.cpp b/DAQ_FW/src/wheelSpeed.cpp index f315966..eff9ba0 100644 --- a/DAQ_FW/src/wheelSpeed.cpp +++ b/DAQ_FW/src/wheelSpeed.cpp @@ -2,16 +2,33 @@ #include #include -void wheelSpeedDisplay(int volatile wheelPulses, int wheelNumber){ +void wheelSpeedDisplay(int volatile WP1, int volatile WP2, int volatile WP3, int volatile WP4){ - // calculate RPM from wheel pulse count - int RPM = (wheelPulses/49.0)*60; // subject to change based on tire + // average wheel pulse counts + + //int wheelPulses = 0.25*(WP1 + WP2 + WP3 + WP4); + int wheelPulses = WP1; + + // calculate angular velocity from wheel pulse count + + int omega = (wheelPulses / 49.0)*2*3.14; // wheel pulses divided by 49.0 indents per tire, in radians + + // convert to linear velocity + + int velocity = 0.25 * omega * 3.6; // for r = 10", 3.6 is proportionality const from m/s to km/h + + // calculate average RPM from wheel pulse count + //int RPM = (wheelPulses/49.0)*60; // subject to change based on tire + // print results - Serial.print("Wheel "); - Serial.print(wheelNumber); - Serial.print(" RPM = "); - Serial.println(RPM); + Serial.print("Speed = "); + Serial.println(velocity, 0); // print with no decimal places + + //Serial.print("Wheel "); + //Serial.print(wheelNumber); + //Serial.print(" RPM = "); + //Serial.println(RPM); // print wheel pulse count for testing purposes //Serial.print(wheelPulses); diff --git a/DAQ_FW/src/wheelSpeed.h b/DAQ_FW/src/wheelSpeed.h index 4d22e26..7569ac0 100644 --- a/DAQ_FW/src/wheelSpeed.h +++ b/DAQ_FW/src/wheelSpeed.h @@ -4,6 +4,6 @@ #include #include -void wheelSpeedDisplay(int volatile wheelPulses, int wheelNumber); +void wheelSpeedDisplay(int volatile WP1, int volatile WP2, int volatile WP3, int volatile WP4); #endif \ No newline at end of file