From: Manfred Steiner Date: Fri, 26 Jul 2024 18:07:45 +0000 (+0200) Subject: Testsoftware unit R2R, Motor X-Git-Url: https://git.htl-mechatronik.at/public/?a=commitdiff_plain;h=3ac184dbc267dfe85eefe1488bda850e822d7bc5;p=nano-x-base.git Testsoftware unit R2R, Motor --- diff --git a/software/test_2024-07-23/src/main.cpp b/software/test_2024-07-23/src/main.cpp index 1f2a0d4..c51cdac 100644 --- a/software/test_2024-07-23/src/main.cpp +++ b/software/test_2024-07-23/src/main.cpp @@ -11,6 +11,8 @@ #include "units/seg7.hpp" #include "units/poti.hpp" #include "units/encoder.hpp" +#include "units/r2r.hpp" +#include "units/motor.hpp" extern "C" { void __cxa_pure_virtual () { @@ -42,6 +44,8 @@ extern "C" { Seg7 seg7; Poti poti; Encoder encoder; + R2r r2r; + Motor motor; } @@ -67,7 +71,7 @@ int main () { // Nano-644 LEDs (Green, Orange, Red) DDRC |= (1 << DDC4) | (1 << DDC3) | (1 << DDC2); PORTC &= ~((1 << PORT4) | (1 << PORT3) | (1 << PORT2)); - + // Nano-644 push button SW2 DDRC &= ~(1 << DDC5); PORTC |= (1 << PORT5); // enable internal pullup resistor @@ -93,7 +97,7 @@ int main () { printf("======================================"); - TestUnit *unit[] = { &led, &sw, &rgb, &seg7, &poti, &encoder }; + TestUnit *unit[] = { &motor, &led, &sw, &rgb, &seg7, &poti, &encoder, &r2r }; for (uint8_t i = 0; i < sizeof(unit) / sizeof(unit[0]); i++) { TestUnit *pu = unit[i]; @@ -133,8 +137,14 @@ ISR (TIMER2_COMPA_vect) { // every 100us static uint16_t timer500ms = 0; static uint8_t timer100us = 0; + if (encoder.enabled) { + encoder.tick100us(); + } + if (motor.enabled) { + motor.tick100us(); + } + timer100us++; - encoder.tick100us(); if (timer100us >= 10) { timer100us = 0; if (timer1ms > 0) { diff --git a/software/test_2024-07-23/src/units/encoder.cpp b/software/test_2024-07-23/src/units/encoder.cpp index b42647b..3b8ce8f 100644 --- a/software/test_2024-07-23/src/units/encoder.cpp +++ b/software/test_2024-07-23/src/units/encoder.cpp @@ -22,6 +22,7 @@ void Encoder::cleanup () { DDRB &= ~((1 << PB2) | (1 << PB1) | (1 << PB0)); PORTB &= ~((1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0)); + enabled = 0; } int8_t Encoder::run (uint8_t subtest) { @@ -30,6 +31,7 @@ int8_t Encoder::run (uint8_t subtest) { printf("init"); DDRB &= ~((1 << PB2) | (1 << PB1) | (1 << PB0)); PORTB |= (1 << PORTB2) | (1 << PORTB1) | (1 << PORTB0); // enable pullup + enabled = 1; return 0; } @@ -59,7 +61,7 @@ struct EncoderState { }; void Encoder::tick100us () { - static EncoderState lastState = { 1, 1 };; + static EncoderState lastState = { 1, 1 }; static EncoderState lastStableState = { 1, 1 }; if ((DDRB & 0x03) || (PORTB & 0x07) != 0x07) { diff --git a/software/test_2024-07-23/src/units/encoder.hpp b/software/test_2024-07-23/src/units/encoder.hpp index 99aaed0..f28584c 100644 --- a/software/test_2024-07-23/src/units/encoder.hpp +++ b/software/test_2024-07-23/src/units/encoder.hpp @@ -7,10 +7,11 @@ class Encoder : public TestUnit { public: + uint8_t enabled; int8_t count; public: - Encoder () { reset(); }; + Encoder () { reset(); enabled = 0; }; virtual void cleanup (); virtual int8_t run (uint8_t subtest); virtual const char *getName () { return "Encoder"; } diff --git a/software/test_2024-07-23/src/units/led.cpp b/software/test_2024-07-23/src/units/led.cpp index 0f4b91b..fe48a40 100644 --- a/software/test_2024-07-23/src/units/led.cpp +++ b/software/test_2024-07-23/src/units/led.cpp @@ -1,8 +1,8 @@ -#include "led.hpp" #include #include #include +#include "led.hpp" #include "../main.hpp" void Led::cleanup () { diff --git a/software/test_2024-07-23/src/units/motor.cpp b/software/test_2024-07-23/src/units/motor.cpp new file mode 100644 index 0000000..be6abd8 --- /dev/null +++ b/software/test_2024-07-23/src/units/motor.cpp @@ -0,0 +1,107 @@ +#include +#include +#include + +#include "motor.hpp" +#include "../main.hpp" + +void Motor::cleanup () { + ADMUX = 0; + ADCSRA = 0; + TCCR0A = 0; + TCCR0B = 0; + DDRB &= ~((1 << PB4) | (1 << PB3)); + PORTA &= ~(1 << PORTA3); + enabled = 0; +} + +int8_t Motor::run (uint8_t subtest) { + switch (subtest) { + case 0: { + printf("init"); + ADMUX = (1 << ADLAR) | (1 << REFS0); // ADC0, VREF=AVCC=3.3V + ADCSRA = (1 << ADEN) | 7; // ADC Enable, Prescaler 128 + TCCR0A = (1 << COM0A1) | (1 << WGM01) | (1 << WGM00); // Fast PWM on OC0A + // TCCR0B = (1 << CS02) | ( 1 << CS00); // f = 12 MHz / 1024 = 11,71875 kHz -> fPWM=45Hz + TCCR0B = (1 << CS02); // f = 12 MHz / 256 = 46,875 kHz -> fPWM=183,1Hz + DDRB |= (1 << PB4) | (1 << PB3); // Motor enable + PORTA |= (1 << PORTA3); // push button for Motor enable control + enabled = 1; + return 0; + } + + case 1: { + printf("\n"); + while (wait(10) == EOF) { + + ADCSRA |= (1 << ADSC); // start ADC + while (ADCSRA & (1 << ADSC)) {} // wait for result + printf("\r => ADC0=%3d", ADCH); + + ADMUX = (1 << ADLAR) | (1 << REFS1) | (1 << REFS0) | 2; // ADC2, VREF=2.5V + + uint8_t dutyCycle = 0xff - ADCH; + if (dutyCycle <= 1) { + dutyCycle = 0; + } else if (dutyCycle > 254) { + dutyCycle = 255; + } + OCR0A = dutyCycle; + printf(" PWM/OC0A=%3d", dutyCycle); + + ADCSRA |= (1 << ADSC); // start ADC + while (ADCSRA & (1 << ADSC)) {} // wait for result + printf(" ADC2=%3d", ADCH); + ADMUX = (1 << ADLAR) | (1 << REFS0); // ADC0, VREF=AVCC=3.3V + + if ((PINA & (1<< PA3)) == 0) { + PORTB &= ~(1 << PORTB4); + } else { + PORTB |= (1 << PORTB4); + } + + uint16_t timer; + ATOMIC_BLOCK(ATOMIC_FORCEON) { + timer = rpmTimer; + } + float rpm = 60.0 / (float)timer / 0.0001; + if (timer > 0) { + printf(" n= %4d U/min", (int)rpm); + } else { + printf(" no rotation"); + } + + } + return 0; + } + + case 2: { + printf("\r => end"); + break; + } + } + + return -1; +} + +void Motor::tick100us () { + static uint16_t timerH = 0; + static uint16_t timerL = 0; + static uint8_t pinb = 0; + if ((PINB & 0x01) && PINB != pinb && timerL > 10) { + rpmTimer = timerL + timerH; + timerL = 0; + timerH = 0; + } + if (PINB & 0x01) { + timerH = timerH < 0x4000 ? timerH + 1 : 0x4000; + } else { + timerL = timerL < 0x4000 ? timerL + 1 : 0x4000; + } + if (timerH >= 0x4000 || timerL >= 0x4000) { + rpmTimer = 0; // no ratation detected + } + pinb = PINB; +} + + diff --git a/software/test_2024-07-23/src/units/motor.hpp b/software/test_2024-07-23/src/units/motor.hpp new file mode 100644 index 0000000..35fcf9c --- /dev/null +++ b/software/test_2024-07-23/src/units/motor.hpp @@ -0,0 +1,20 @@ +#ifndef MOTOR_HPP +#define MOTOR_HPP + +#include +#include "../main.hpp" + +class Motor : public TestUnit { + public: + uint8_t enabled; + uint16_t rpmTimer; + + public: + Motor () { enabled = 0; rpmTimer = 0; }; + virtual void cleanup (); + virtual int8_t run (uint8_t subtest); + virtual const char *getName () { return "Motor"; } + void tick100us (); +}; + +#endif \ No newline at end of file diff --git a/software/test_2024-07-23/src/units/r2r.cpp b/software/test_2024-07-23/src/units/r2r.cpp new file mode 100644 index 0000000..40b24e1 --- /dev/null +++ b/software/test_2024-07-23/src/units/r2r.cpp @@ -0,0 +1,43 @@ +#include +#include + +#include "r2r.hpp" +#include "../main.hpp" + +void R2r::cleanup () { + ADMUX = 0; + ADCSRA = 0; +} + +int8_t R2r::run (uint8_t subtest) { + switch (subtest) { + case 0: { + printf("init"); + ADMUX = (1 << REFS0) | 2; // ADC2, VREF=AVCC=3.3V + ADCSRA = (1 << ADEN) | 7; // ADC Enable, Prescaler 128 + return 0; + } + + case 1: { + printf("\n"); + while (wait(10) == EOF) { + printf("\r => Measure ADC2: "); + ADCSRA |= (1 << ADSC); // start ADC + while (ADCSRA & (1 << ADSC)) {} // wait for result + printf("%4d (0x%03x)", ADC, ADC); + uint8_t sw = (ADC + 32) / 64; + printf(" SW9:6 = %d %d% d %d ", sw >> 3, (sw >> 2) & 0x01, (sw >> 1) & 0x01, sw & 0x01 ); + } + return 0; + } + + case 2: { + printf("\r => R2R end%20s", " "); + break; + } + } + + return -1; +} + + diff --git a/software/test_2024-07-23/src/units/r2r.hpp b/software/test_2024-07-23/src/units/r2r.hpp new file mode 100644 index 0000000..974c7a7 --- /dev/null +++ b/software/test_2024-07-23/src/units/r2r.hpp @@ -0,0 +1,15 @@ +#ifndef R2R_HPP +#define R2R_PP + +#include +#include "../main.hpp" + +class R2r : public TestUnit { + public: + R2r () {}; + virtual void cleanup (); + virtual int8_t run (uint8_t subtest); + virtual const char *getName () { return "R2R"; } +}; + +#endif \ No newline at end of file