-
Notifications
You must be signed in to change notification settings - Fork 223
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Weird issue with two u8 ranged loops #569
Comments
Hey, just produced a minimum version of what you provided, can you attempt to run this (tested on an Arduino UNO) #![no_std]
#![no_main]
use arduino_hal::prelude::*;
use panic_halt as _;
#[arduino_hal::entry]
fn main() -> ! {
let dp = arduino_hal::Peripherals::take().unwrap();
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);
loop {
for x in (0..=255).rev() {
ufmt::uwriteln!(&mut serial, "L1 {}", x).unwrap_infallible();
arduino_hal::delay_ms(10);
}
for x in 0..=255 {
ufmt::uwriteln!(&mut serial, "L2 {}", x).unwrap_infallible();
arduino_hal::delay_ms(10);
}
}
} (Created from a new project generated with |
Hi @CoolSlimbo . Good idea. I tried commenting out everything as you suggested and it started working fine. But as soon as I activate the line that sets red LED's duty: Then I comment the red LED line and activate green and blue LED lines, then everything is fine. Loops are alternating. One difference between red LED and the others is that red uses I also tried to use the other pin One thing I should also add is the red LED For anyone interested I post the complete code that triggers the issue down below: #![no_std]
#![no_main]
use arduino_hal::prelude::_unwrap_infallible_UnwrapInfallible;
use arduino_hal::hal::port::{ PB3, PD5, PD6 };
use arduino_hal::simple_pwm::{ Timer0Pwm, Timer2Pwm, Prescaler, IntoPwmPin };
use arduino_hal::port::{ Pin, mode };
use panic_halt as _;
struct LedRGB {
red_output: Pin<mode::PwmOutput<Timer2Pwm>, PB3>,
green_output: Pin<mode::PwmOutput<Timer0Pwm>, PD6>,
blue_output: Pin<mode::PwmOutput<Timer0Pwm>, PD5>,
}
#[arduino_hal::entry]
fn main() -> ! {
let dp = arduino_hal::Peripherals::take().unwrap();
let pins = arduino_hal::pins!(dp);
let timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64);
let timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);
let mut led_rgb = LedRGB {
red_output: pins.d11.into_output().into_pwm(&timer2),
green_output: pins.d6.into_output().into_pwm(&timer0),
blue_output: pins.d5.into_output().into_pwm(&timer0),
};
led_rgb.red_output.enable();
led_rgb.green_output.enable();
led_rgb.blue_output.enable();
let delay_ms = 10;
loop {
for x in (0..=255).rev() {
led_rgb.red_output.set_duty(x);
led_rgb.green_output.set_duty(255 - x);
let blue: u8 = if x >= 128 { 128 - (255 - x) } else { 127 - x };
led_rgb.blue_output.set_duty(blue);
ufmt::uwriteln!(&mut serial, "LOOP 1: RED: {}, GREEN: {}, BLUE: {}", x, 255 - x, blue).unwrap_infallible();
arduino_hal::delay_ms(delay_ms);
}
// This loop gets stuck and loops forever, but the first loop and this one should alternate
for y in 0..=255 {
// Commenting out below line will make the code work as expected.
led_rgb.red_output.set_duty(y);
// LEDs connected to Timer0Pwm work fine. Loops will alternate when I use them
led_rgb.green_output.set_duty(255 - y);
let blue: u8 = if y >= 128 { 128 - (255 - y) } else { 127 - y };
led_rgb.blue_output.set_duty(blue);
ufmt::uwriteln!(&mut serial, "LOOP 2: RED: {}, GREEN: {}, BLUE: {}", y, 255 - y, blue).unwrap_infallible();
arduino_hal::delay_ms(delay_ms);
}
}
} |
Have you tried with a different timer to Timer2? |
Trying with |
Though I tried one more thing and got interesting result: for y in 0..=255 {
//led_rgb.red_output.set_duty(y);
// LEDs connected to Timer0Pwm work fine. Loops will alternate when I use them
led_rgb.green_output.set_duty(y);
let blue: u8 = if y >= 128 { 128 - (255 - y) } else { 127 - y };
led_rgb.blue_output.set_duty(blue);
ufmt::uwriteln!(&mut serial, "LOOP 2: RED: {}, GREEN: {}, BLUE: {}", y, 255 - y, blue).unwrap_infallible();
arduino_hal::delay_ms(delay_ms);
}
So at this point setting the duty cycle to |
That is. I'll have to dig around to find my RGB LED, and I'm about to help with another issue. I'll take your last full posted example and see what I can make of it on my Arduino and LED. Also, for future code snippets, please add |
Then what I did shocked the civilized world: led_rgb.green_output.set_duty(255 - y);
let blue: u8 = if y >= 128 { 128 - (255 - y) } else { 127 - y };
led_rgb.blue_output.set_duty(blue);
led_rgb.red_output.set_duty(y); I restored the code to it's original bugging version, and simply moved Thank you for looking into this. Cheers! |
That's what it could be. I guess I might fill my night with some figuring out a) what tf AVR assembly looks like, and b) figuring out how it results. Fell free to close the issue, but I'll post updates on what I find. |
So, I attempted to run your code provided here, however, mine seemed to have run fine, without any issue, looping back and fourth between the two loops successfully. So, to determine the issue that may be present, can I ask what toolchain version you are running on, and what commit your |
Sure. Here it is: [dependencies.arduino-hal]
git = "https://github.com/rahix/avr-hal"
rev = "3e362624547462928a219c40f9ea8e3a64f21e5f"
features = ["arduino-uno"] And [toolchain]
channel = "nightly-2024-03-22"
components = ["rust-src"]
profile = "minimal" |
Okay... very confused now. The code example you said wasn't working, works fine for me on my UNO, and we have matching HAL's and toolchains... This could've just been a single time fluke of some form with your compiler being special. Since I can't reproduce on a fresh install, and you've resolved it yourself, I don't see a reason as to why we have to keep this open. If anyone has this issue in the future, and comes to this issue, feel free to open it up again. (Free to close it now buru) |
Strange indeed. I also tried the same code with an original UNO board and result is the same. I'll close this issue now as it seems related to my GCC and GCC-AVR setup. My GCC version is 10.2.1 and GCC-AVR is 5.4.0+Atmel3.6.2 on a Debian 11 system. So if anyone else bumps into this bug these might help. Finally can you post the versions of your GCC and GCC-AVR packages? Thanks a lot. |
Rocking avr-gcc 14.1.0. So could be a difference between platforms building on, or our avr-gcc versions, as it seems. |
I finally updated my Debian system from version 11 to 12. Which comes with: GCC version 12.2 This update totally resolved the issue. So the bug was probably related to GCC version. If anybody comes across this behavior of loops not conforming, I recommend updating the development environment. Thanks. |
I wrote this program to control an RGB LED module and it should more or less seamlessly cycle around different colors. I used simple PWM for this.
The platform I use is Arduino UNO with atmega328pb chip. And the PWM setup is:
Problem is after the first loop that represents a reversed ramp it gets stuck on the second loop that is the ascending ramp. I can't figure out what's wrong with it:
When I follow the console output, I see the first loop and the values are correct, then it jumps to second loop and values are again correct, but the program gets stuck on the second loop repeating it again and again forever.
When I remove the = sign from the second range loop ie:
for y in 0..255
instead offor y in 0..=255
It works as expected with alternating pattern of loops, but the ramp doesn't reach 255 value and the result is one value less than required.
When I test the code with
0..=255
on regular PC Rust on Linux I get the alternating pattern of loops working as expected.The text was updated successfully, but these errors were encountered: