Registers Not Updating Inside Class Methods - Page 1
Forum section: electronics / beginners

author: Lovro7
author_rank: Contributor
timestamp: February 08, 2025, 09:57:51 pm
content: Hallo,I'm working on an AVR-based project using C++ and encountered an issue where registers do not update as expected inside my class methods. When I try to read a register after modifying it, it returns a different value than what I set.Here’s the relevant code:Code:stepper::stepper(uint16_t step_n) {_step_n = step_n;DDRB |= (1 << 1);TCCR1B |= (1 << WGM12);TCCR1A |= (1 << COM1A0);OCR1A = 0xFFFF;TIMSK1 |= (1 << OCIE1A);//TCCR1B |= (1 << CS12);sei();}void stepper::setSpeed(uint16_t steps_per_second) {OCR1B = (125000 / steps_per_second) - 1;}void stepper::startMoving() {TCCR1B |= (1 << CS12);}The problem:When calling setSpeed(), OCR1B does not appear to be updated correctly.When calling startMoving(), TCCR1B does not seem to retain the expected value.If I read back the register, I get a different value than what was assigned.Could this be an issue with compiler optimizations, register shadowing, or something else? Any insights would be greatly appreciated!

author: ledtester
author_rank: Super Contributor
timestamp: February 08, 2025, 11:36:43 pm
content: The absolute simplest program which demonstrates the problem would be helpful.Perhaps this discussion is relevant:https://forum.arduino.cc/t/setting-timer-registers-in-a-library-tccr1a-tccr1b-etc/131630i.e. are you trying to set the registers in a constructor of a global object before main() is getting called and then the Arduino initialization code is clobbering your values?

author: Lovro7
author_rank: Contributor
timestamp: February 09, 2025, 12:28:04 am
content: Thank you for your response. That was exactly the mistake. The code is now working, except the motor doesn't stop. I still need to figure out why.I am also sending the code alongstepper.h:Code:#ifndef stepper_h#define stepper_h#include "Arduino.h"#define LEFT 0#define RIGHT 1class stepper{public:stepper(uint16_t step_n);void init();void setSpeed(uint16_t sps);void setSpeedEff(uint16_t sps);void setSpeedRPM(uint8_t rpm);void setDirection(bool dir);void moveForNSteps(unsigned long n);void moveForNStepsDir(unsigned long n, bool dir);void startMoving();void startMovingDir(bool dir);void stopMoving();private:uint16_t _step_n;};#endifstepper.cpp:Code:#include "Arduino.h"#include "stepper.h"#include "avr/interrupt.h"volatile unsigned long set_stepps = 0;volatile unsigned long stepp_count = 0;volatile bool stop_enable = 0;stepper::stepper(uint16_t step_n){_step_n = step_n;}void stepper::init(){DDRB |= (1 << PORTB1);TCCR1A = (1 << COM1A0);TCCR1B = (1 << WGM12);TIMSK1 = (1 << OCIE1A);sei();}void stepper::setSpeed(uint16_t sps){OCR1A = (15625 / sps) + 1;}void stepper::setSpeedEff(uint16_t sps){OCR1A = sps;}void stepper::setDirection(bool dir){if(dir){PORTB |= 0x01;}else{PORTB &= ~(0x01);}}void stepper::moveForNSteps(unsigned long n){stop_enable = true;set_stepps = n;TCCR1B |= (1 << CS12);}void stepper::moveForNStepsDir(unsigned long n, bool dir){if(dir){PORTB |= 0x01;}else{PORTB &= ~(0x01);}stop_enable = true;set_stepps = n;TCCR1B |= (1 << CS12);}void stepper::startMoving(){TCCR1B |= (1 << CS12);}void stepper::stopMoving(){TCCR1B &= ~(1 << CS12);}ISR(TIMER1_COMPB_vect){if(stop_enable){if ((stepp_count >> 1) == set_stepps) {TCCR1B &= ~(1 << CS12);stepp_count = 0;}}}main.cpp (main.ino):Code:#include <Arduino.h>#include "stepper.h"stepper motor(150);void setup(){motor.init();motor.setDirection(LEFT);motor.setSpeed(100);}void loop(){motor.startMoving();delay(2000);motor.stopMoving();delay(2000);}

author: ledtester
author_rank: Super Contributor
timestamp: February 09, 2025, 06:32:17 am
content: In this code (which appears a couple of times):Code:TCCR1B &= ~(1 << CS12);it my not be your problem but as a matter of safety I would clear out all three bits -- CS1[2:0] -- not just CS12 to stop the timer.