| General > General Technical Chat |
| Schmitt Buffer/Trigger with Encoder and buttons - Inverting... |
| << < (4/8) > >> |
| elcrni:
Thanks MarkF! I have tried different approach now and moved off Interrupt pins. My encoder code now runs inside the main loop (i guess at 16MHz) on atmega2560 controller. I need to slow this way down as there is no need for it to run this fast. Again, i am seeing errors in radio signal decoding probably due to the fact that encoder now is running inside main loop. how do i slow down encoder checking rate/speed to something more reasonable, like 500Hz? (assuming someone has experience with arduino code) --- Code: ---void encoder_brightness(){ state=(state<<1) | digitalRead(CLK_PIN) | 0xe000; if (state==0xf000){ state=0x0000; if(digitalRead(DATA_PIN)) counter++; else counter--; if (counter>15) {(counter = 15);} if (counter<0) {(counter = 0);} } --- End code --- and encoder_brightness() runs inside main loop. I know we are now outside my main topic but i now when we are at it, i would really like to sort this one out. Many thanks, Alek |
| MarkF:
See if this helps: And a little pseudo code as an outline: --- Code: ---// global variables int count=0; // encoder increment/decrement count //************************************************************ void setup() { // Set encoder pins as input . . . // Setup Timer 1 for 500Hz . . . // Enable interrupts sei(); } //************************************************************ void loop() { int local_count; if (count != 0) { // Get encoder turn count and reset it for future turns local_count = count; // get encoder turns count = 0; // reset global turn count // Use local_count to control your object, brightness or whatever . . . encoder_brightness(local_count); // example: increase or decrease brightness by local_count amount } // Do other non-encoder related processing . . . } //************************************************************ ISR(TIMER1_CMPA_vect) { // Read encoder lines . . . // Decode incrementing or decrementing count if (clockwise turn) count++; else if (counter_clockwise turn) count--; } --- End code --- |
| elcrni:
thanks man, thats some nice material. i am not too familiar with interrupt timers, so will have to dive in more. on a side note, what would happen if i just use millis and set it up to 2 millis for encoder checkup? still sort of 500Hz...? thanks alek |
| MarkF:
--- Quote from: elcrni on March 17, 2021, 05:50:15 pm ---thanks man, thats some nice material. i am not too familiar with interrupt timers, so will have to dive in more. on a side note, what would happen if i just use millis and set it up to 2 millis for encoder checkup? still sort of 500Hz...? thanks alek --- End quote --- That would allow you to approximate reading and decoding the encoder pins. It will NOT however allow you to do other tasks. Not worth the effort in my opinion. I typically do non-critical processing in the loop() function (such as updating a display screen) while sampling user inputs in the interrupt service code (basically just setting global flags to be used in the loop() function)(minimal processing in the interrupt code). I would concentrate on setting up the code and the interrupt service routine (ISR). You can toggle a pin inside the ISR() routine to check your setup and timing. Then, add the encoder capability afterwards when you are confident with the basic code layout and timing. Remember: the ISR() function MUST complete BEFORE the next interrupt occurs. One key edit to my previous pseudo code: Add check for (count != 0), so you only execute that code within the loop when a change has been detected. (see edited code) |
| elcrni:
ok, i took this the other way around, haha. First did the encoder but now hang at timing, still not sure how to pull this off. my current code now goes as follows: --- Code: ---#include <EEPROM.h> #include <LedControl.h> #include <ezButton.h> #include <TimeLib.h> #include <RTClib.h> #include <OneWire.h> #include <DS1307RTC.h> #define MAXIMCCLD 12 // output - CS/LOAD #define MAXIMCCCLK 11 // output - CLOCK #define MAXIMCCDATA 10 // output - DATA #define DS1307_I2C_ADDRESS 0x68 // define the RTC I2C address ezButton button(7); // create ezButton object that attach to pin 7; LedControl MaximCC=LedControl(MAXIMCCDATA, MAXIMCCCLK, MAXIMCCLD, 1); // Define pins for Maxim 72xx and how many 72xx we use int LED = 5; int LED2 = 9; volatile signed int counter_hour_start = EEPROM.read(2); volatile signed int counter_minute_start = EEPROM.read(3); volatile signed int counter_hour_end = EEPROM.read(4); volatile signed int counter_minute_end = EEPROM.read(5); // usually the rotary encoders three pins have the ground pin in the middle enum PinAssignments { encoderPinA = 2, // right encoderPinB = 3, // left }; // a counter for the dial signed int lastReportedPos_hour_start = 1; // change management signed int lastReportedPos_minute_start = 1; // change management signed int lastReportedPos_hour_end = 1; // change management signed int lastReportedPos_minute_end = 1; // change management // interrupt service routine vars boolean A_set = false; boolean B_set = false; int previousSecond = 0; int tensofhours, singlehours, tensofminutes, singleminutes,tensofhours1, singlehours1, tensofminutes1, singleminutes1; //============================================================================== // SETUP //============================================================================== void setup() { pinMode(LED, OUTPUT); pinMode(LED2, OUTPUT); pinMode(encoderPinA, INPUT); pinMode(encoderPinB, INPUT); // encoder pin on interrupt 0 (pin 2) attachInterrupt(0, doEncoderA, CHANGE); // encoder pin on interrupt 1 (pin 3) attachInterrupt(1, doEncoderB, CHANGE); MaximCC.shutdown(0,false); MaximCC.setIntensity(0,15); MaximCC.clearDisplay(0); button.setDebounceTime(50); // set debounce time to 50 milliseconds button.setCountMode(COUNT_FALLING); setSyncProvider(RTC.get); // the function to get the time from the RTC tensofhours = counter_hour_start / 10; singlehours = counter_hour_start % 10; tensofminutes = counter_minute_start / 10; singleminutes = counter_minute_start % 10; tensofhours1 = counter_hour_end / 10; singlehours1 = counter_hour_end % 10; tensofminutes1 = counter_minute_end / 10; singleminutes1 = counter_minute_end % 10; } //============================================================================== // LOOP //============================================================================== void loop() { tasksEverySecond(); button.loop(); // MUST call the loop() function first unsigned long count = button.getCount(); if (count>0) { encoder_alarm(); } } //============================================================================== // tasksEverySecond //============================================================================== void tasksEverySecond() { if (second() != previousSecond) { previousSecond = second(); displayRtcTime(); ledTest(); } } //============================================================================== // ENCODER ALARM //============================================================================== void encoder_alarm(){ unsigned long count = button.getCount(); // reset button count when we cycle through all digit groups and set an alarm if (count > 6) { button.resetCount(); digitalWrite(LED, LOW); } //--------------------- HOURS alarm STARTS at ------------------------// if (lastReportedPos_hour_start != counter_hour_start) { if (counter_hour_start>23) {(counter_hour_start = 0);} if (counter_hour_start<0) {(counter_hour_start = 23);} tensofhours = counter_hour_start / 10; singlehours = counter_hour_start % 10; lastReportedPos_hour_start = counter_hour_start; } EEPROM.update(2,counter_hour_start); //--------------------- MINUTES alarm STARTS at ------------------------// if (lastReportedPos_minute_start != counter_minute_start) { if (counter_minute_start>59) {(counter_minute_start = 0);} if (counter_minute_start<0) {(counter_minute_start = 59);} tensofminutes = counter_minute_start / 10; singleminutes = counter_minute_start % 10; lastReportedPos_minute_start = counter_minute_start; EEPROM.update(3,counter_minute_start); } //--------------------- HOURS alarm ENDS at ------------------------// if (lastReportedPos_hour_end != counter_hour_end) { if (counter_hour_end>23) {(counter_hour_end = 0);} if (counter_hour_end<0) {(counter_hour_end = 23);} tensofhours1 = counter_hour_end / 10; singlehours1 = counter_hour_end % 10; lastReportedPos_hour_end = counter_hour_end; } EEPROM.update(4,counter_hour_end); //--------------------- MINUTES alarm ENDS at ------------------------// if (lastReportedPos_minute_end != counter_minute_end) { if (counter_minute_end>59) {(counter_minute_end = 0);} if (counter_minute_end<0) {(counter_minute_end = 59);} tensofminutes1 = counter_minute_end / 10; singleminutes1 = counter_minute_end % 10; lastReportedPos_minute_end = counter_minute_end; EEPROM.update(5,counter_minute_end); } //--------------------- 7 Segment display ------------------------// if (count == 1 || count == 6) { MaximCC.setChar(0,7,tensofhours,false); MaximCC.setChar(0,6,singlehours,true); MaximCC.setChar(0,5,tensofminutes,false); MaximCC.setChar(0,4,singleminutes,true); MaximCC.setChar(0,3,tensofhours1,false); MaximCC.setChar(0,2,singlehours1,true); MaximCC.setChar(0,1,tensofminutes1,false); MaximCC.setChar(0,0,singleminutes1,true); digitalWrite(LED, HIGH); } if (count == 2) { MaximCC.setChar(0,7,tensofhours,false); MaximCC.setChar(0,6,singlehours,true); } else if (count != 1 && count != 6){ MaximCC.setChar(0,6,singlehours,false); } if (count == 3) { MaximCC.setChar(0,5,tensofminutes,false); MaximCC.setChar(0,4,singleminutes,true); } else if (count != 1 && count != 6) { MaximCC.setChar(0,4,singleminutes,false); } if (count == 4) { MaximCC.setChar(0,3,tensofhours1,false); MaximCC.setChar(0,2,singlehours1,true); } else if (count != 1 && count != 6) { MaximCC.setChar(0,2,singlehours1,false); } if (count == 5) { MaximCC.setChar(0,1,tensofminutes1,false); MaximCC.setChar(0,0,singleminutes1,true); } else if (count != 1 && count != 6) { MaximCC.setChar(0,0,singleminutes1,false); } } //============================================================================== // displayRtcTime //============================================================================== void displayRtcTime() { unsigned long count = button.getCount(); if (count == 0){ MaximCC.setChar(0, 7, (hour() / 10), false); MaximCC.setChar(0, 6, (hour() % 10), false); MaximCC.setChar(0, 5, '-', false); MaximCC.setChar(0, 4, (minute() / 10), false); MaximCC.setChar(0, 3, (minute() % 10), false); MaximCC.setChar(0, 2, '-', false); MaximCC.setChar(0, 1, (second() / 10), false); MaximCC.setChar(0, 0, (second() % 10), false); } } //============================================================================== // ledTest //============================================================================== void ledTest(){ int midnight; int powersaving; int startTime = counter_hour_start * 100 + counter_minute_start; int endTime = counter_hour_end * 100 + counter_minute_end; int timeNow = hour() * 100 + minute(); if (endTime == 0000 && startTime != 0000){ endTime = 2359; } if (timeNow >= startTime && timeNow < endTime) { powersaving = true; } else { powersaving = false; } if (powersaving == true){ digitalWrite(LED2, HIGH); } else { digitalWrite(LED2, LOW); } } // Interrupt on A changing state void doEncoderA() { unsigned long count = button.getCount(); // Test transition, did things really change? if ( digitalRead(encoderPinA) != A_set ) { // debounce once more A_set = !A_set; // adjust counter + if A leads B if (( A_set && !B_set ) && (count == 2)) counter_hour_start += 1; if (( A_set && !B_set ) && (count == 3)) counter_minute_start += 1; if (( A_set && !B_set ) && (count == 4)) counter_hour_end += 1; if (( A_set && !B_set ) && (count == 5)) counter_minute_end += 1; } } // Interrupt on B changing state, same as A above void doEncoderB() { unsigned long count = button.getCount(); if ( digitalRead(encoderPinB) != B_set ) { B_set = !B_set; // adjust counter - 1 if B leads A if (( B_set && !A_set ) && (count == 2)) counter_hour_start -= 1; if (( B_set && !A_set ) && (count == 3)) counter_minute_start -= 1; if (( B_set && !A_set ) && (count == 4)) counter_hour_end -= 1; if (( B_set && !A_set ) && (count == 5)) counter_minute_end -= 1; } } --- End code --- Many thanks, Alek |
| Navigation |
| Message Index |
| Next page |
| Previous page |