Commit 3ac184dbc267dfe85eefe1488bda850e822d7bc5
receivedFri, 26. Jul 2024, 20:07:52 (by user sx)
Fri, 26 Jul 2024 18:07:52 +0000 (20:07 +0200)
authorManfred Steiner <sx@htl-kaindorf.at>
Fri, 26 Jul 2024 18:07:45 +0000 (20:07 +0200)
committerManfred Steiner <sx@htl-kaindorf.at>
Fri, 26 Jul 2024 18:07:45 +0000 (20:07 +0200)
8 files changed:
software/test_2024-07-23/src/main.cpp
software/test_2024-07-23/src/units/encoder.cpp
software/test_2024-07-23/src/units/encoder.hpp
software/test_2024-07-23/src/units/led.cpp
software/test_2024-07-23/src/units/motor.cpp [new file with mode: 0644]
software/test_2024-07-23/src/units/motor.hpp [new file with mode: 0644]
software/test_2024-07-23/src/units/r2r.cpp [new file with mode: 0644]
software/test_2024-07-23/src/units/r2r.hpp [new file with mode: 0644]

index 1f2a0d4784ac101bed1716674041a04b0c27eb8c..c51cdac0d46dcf1989c82506beb080530b91fb11 100644 (file)
@@ -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) {
index b42647bb50cf76672a78004ddf9a0e7b86344112..3b8ce8faba4b1decb4db66ae254eea70d15f18b8 100644 (file)
@@ -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) {
index 99aaed0521517f9944133af46cd8764ee3090efb..f28584ce309afeb4c085c88ae640feb15ee25ce4 100644 (file)
@@ -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"; }
index 0f4b91b57f88d85ece3e3cddebad43aa55778b2d..fe48a405d98bdc0f9bb637db00dc4b5a48c72e65 100644 (file)
@@ -1,8 +1,8 @@
-#include "led.hpp"
 #include <stdio.h>
 #include <avr/io.h>
 #include <util/delay.h>
 
+#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 (file)
index 0000000..be6abd8
--- /dev/null
@@ -0,0 +1,107 @@
+#include <stdio.h>
+#include <avr/io.h>
+#include <util/atomic.h>
+
+#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 (file)
index 0000000..35fcf9c
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef MOTOR_HPP
+#define MOTOR_HPP
+
+#include <stdint.h>
+#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 (file)
index 0000000..40b24e1
--- /dev/null
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <avr/io.h>
+
+#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 (file)
index 0000000..974c7a7
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef R2R_HPP
+#define R2R_PP
+
+#include <stdint.h>
+#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