Skip to content
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

Can't find devices #3

Closed
riaqn opened this issue Apr 9, 2019 · 22 comments
Closed

Can't find devices #3

riaqn opened this issue Apr 9, 2019 · 22 comments

Comments

@riaqn
Copy link

riaqn commented Apr 9, 2019

I'm trying to run a ds18b20 on my stm32f103. The code is as follows ( pretty much copied from README).
the program gives me

search for devices
search finished

which means no device is found. But if I remove the 4.7k resistor from the circuit, it will actually complain missing pullups, so I assume my circuit connection is correct.

#![no_std]
#![no_main]

extern crate panic_halt;

use onewire::{
    OneWire,
    DeviceSearch,
    ds18b20,
};

use stm32f1xx_hal::{
    prelude::*,
    pac,
    delay,
};
use cortex_m_rt::entry;

use cortex_m_semihosting::{hprintln};

#[entry]
fn main() -> ! {
   let mut cp: cortex_m::Peripherals = cortex_m::Peripherals::take().unwrap();
    let mut dp = pac::Peripherals::take().unwrap();
    let mut flash = dp.FLASH.constrain();

    let mut rcc = dp.RCC.constrain();

    let clocks = rcc.cfgr.freeze(&mut flash.acr);

    let mut gpiob = dp.GPIOB.split(&mut rcc.apb2);
    
    let mut delay = delay::Delay::new(cp.SYST, clocks);
    
    let mut one = gpiob
        .pb11
        .into_open_drain_output(&mut gpiob.crh)
        .downgrade();
        
    let mut wire = OneWire::new(&mut one, false);
    
    if wire.reset(&mut delay).is_err() {
        hprintln!("missing pullup, or error on-line");
        loop {}
    }

    hprintln!("search for devices");
    
    // search for devices
    let mut search = DeviceSearch::new();
    while let Some(device) = wire.search_next(&mut search, &mut delay).unwrap() {
        match device.address[0] {
            ds18b20::FAMILY_CODE => {
                let mut ds18b20 = ds18b20::DS18B20::new(device).unwrap();
                
                // request sensor to measure temperature
                let resolution = ds18b20.measure_temperature(&mut wire, &mut delay).unwrap();
                
                // wait for compeltion, depends on resolution 
                delay.delay_ms(resolution.time_ms());
                
                // read temperature
                let temperature = ds18b20.read_temperature(&mut wire, &mut delay).unwrap();
                hprintln!("{0}", temperature);
            },
            _ => {
                hprintln!("unknown device type");
            }
        }
    }
    hprintln!("search finished");
    loop {}
}
@riaqn
Copy link
Author

riaqn commented Apr 9, 2019

Another finding: If I don't connect the data pin at all, I actually get devices but unrecognized:

00:00:00:00:00:00:00:00
unknown device type
00:00:00:00:00:00:00:80
unknown device type
00:00:00:00:00:00:00:40
unknown device type
00:00:00:00:00:00:00:c0
unknown device type
00:00:00:00:00:00:00:20
unknown device type
00:00:00:00:00:00:00:a0
unknown device type
00:00:00:00:00:00:00:60
unknown device type
00:00:00:00:00:00:00:e0
unknown device type
00:00:00:00:00:00:00:10
unknown device type
00:00:00:00:00:00:00:90
unknown device type
00:00:00:00:00:00:00:50
unknown device type
00:00:00:00:00:00:00:d0
unknown device type
00:00:00:00:00:00:00:30
unknown device type

and this go on and on ad infinitum.

@chernomor
Copy link
Contributor

@riaqn try to set frequency of MCU, something like this:

rcc.cfgr
        .sysclk(64.mhz())
        .pclk1(32.mhz());

after this line:
let mut rcc = dp.RCC.constrain();

@riaqn
Copy link
Author

riaqn commented Apr 9, 2019

@chernomor Thanks for the reply. I did this change; now it's

    let mut rcc = dp.RCC.constrain();

        let clocks = rcc.cfgr.sysclk(64.mhz())
        .pclk1(32.mhz()).freeze(&mut flash.acr);

which is not exactly what you said but I need to convince the borrow checker. However the error persist.

@kellerkindt
Copy link
Owner

Hmm, I had similar issues, when I had it run the debug artifact and when I had semihosting in use. Could you try it without that and in release mode? Maybe blink an LED depending on the result...

@riaqn
Copy link
Author

riaqn commented Apr 13, 2019

@kellerkindt Well. the problem is that I kind of need semihosting to print something to see if it's working. but I guess I can use the serial instead. I will try this out later.

EDIT:
Ahh, I just realized what you mean ( blinking an LED depending on the result). I will try that.

@riaqn
Copy link
Author

riaqn commented Apr 14, 2019

@kellerkindt OK so I tried it with semihosting off (out of Cargo.toml) and debug off (under profile.release)
But it's still not working.

EDIT: ok obviously I need to run cargo run --release. The --release is what got me.

I will try this with semihosting on.

EDIT: so even with semihosting on it still works. So the problem seem to be just release mode vs debug mode. I don't know why. Maybe someone could explain to me.

@tim-seoss
Copy link

FWIW, I stuck a logic analyser on the example code (and also added some debugging with itm) I got:

rustc 1.36.0-nightly (5d20ff4d2 2019-04-18) development build shows a brief 32µs pull down, followed 140µs later by a 604µs reset pulse (with the correct presence response), followed 8.97ms later by another 604µs reset pulse (and correct presense response). There's then nothing else (debug output shows the search complete, but the bus never went low again.

rustc 1.36.0-nightly (5d20ff4d2 2019-04-18) release build shows a 6µs initial pulldown, followed 6µs later by a 484µs reset pulse (with 104µs presence response), followed 486µs later (much quicker) by another 484µs reset pulse and response. The search sequence starts 416µs later.

@riaqn
Copy link
Author

riaqn commented Apr 19, 2019

@tim-seoss Thanks for the investigation. Let's wait someone familir with Cargo to explain.

@chernomor
Copy link
Contributor

It seems rust version is important, I build my project with nightly-2018-11-01. Next builds (december or january) don't works, so I return to nightly-2018-11-01.

@riaqn
Copy link
Author

riaqn commented Apr 19, 2019 via email

@tim-seoss
Copy link

FWIW, it looks like opt-level impacts whether it works. Putting:

[profile.release]
opt-level = 2

in Cargo.toml gets it working, but the other options like 0 or 'z' don't work. You may need to run cargo clean to ensure everything is rebuilt with the correct optimisation level.

@riaqn
Copy link
Author

riaqn commented Apr 19, 2019

OK so my guess is that un-optimized code is too slow and screwed up some time-sensitive initialization?

@tim-seoss
Copy link

tim-seoss commented Apr 20, 2019

OK so my guess is that un-optimized code is too slow and screwed up some time-sensitive initialization?

I don't think that explains the behaviour that I was seeing with the signal analyser (edit: actually perhaps it's missing the presence pulse because it's not sampling it soon enough? I'll check.)

@kellerkindt
Copy link
Owner

kellerkindt commented Apr 20, 2019

Hmm. Because of similar issues I once had (as mentioned above) similar timing issues. I would like to refactor the sleeping/timing part, using the CountDown timer from embedded_hal. But it seems that the time unit (CountDown::Time) would make it platform/chip-hal dependent?
For example, in stm32f1xx-hal CountDown is implemented using Hertz which is located in stm32f1xx-hal.

Am I missing something?

@tim-seoss
Copy link

I'm not at all sure, but depending on what you have in mind, I suppose it might be possible to have the user supply an optional closure to be used for higher resolution sleeping/timing?

@riaqn
Copy link
Author

riaqn commented Jun 6, 2019

Hey guys, I'm again having this issue (no device found), here is my Cargo.toml:

[profile.release]
debug = false
opt-level = 2

rustc version is 1.35.0 (this is what I get with rustc -V. Does that reflect the arm toolchain?)

@riaqn
Copy link
Author

riaqn commented Jun 6, 2019

I tried nightly (1.37.0 20180605) and got the same result.

@riaqn
Copy link
Author

riaqn commented Jun 6, 2019

@chernomor Could you please post the working Cargo.toml you were using with nightly-2018-11-01? I tried with this nightly as well and doesn't work.

@chernomor
Copy link
Contributor

@riaqn

`
[package]
name = "heat-control-f103"
version = "0.1.2"
edition = "2018"

[dependencies]
stm32f103xx-hal = { git="https://github.com/japaric/stm32f103xx-hal.git", rev="45ff8686f16ed0d9d97adfbafb73c21e9e9ee7e8" }
cortex-m-rt = "0.6.3"
panic-halt = "0.2.0"
heapless = "0.3.7"
onewire = "0.3.10"

[dependencies.stm32f103xx]
features = ["rt"]
version = "*"

[dev-dependencies]
cortex-m-rt = "0.6.3"

[build-dependencies]
chrono = "*"

[dependencies.cortex-m]
version-m = "0.5.6"
features = ["inline-asm"]

[dependencies.embedded-hal]
features = ["unproven"]
version = "0.2.1"

[profile.release]
codegen-units = 1
debug = true
lto = true
panic = 'abort'

[features]
doc = []
rt = ["stm32f103xx/rt"]
`

@riaqn
Copy link
Author

riaqn commented Jun 7, 2019

@chernomor Thank you very much. There is lots of things in your file I don't understand.

  1. what is version-m?
  2. I think stm32f103xx is deprecated and we should use stm32f1xx-hal

Also, actually do you mind sharing the whole codebase? I just want to want to make sure my rustc version is ok and my wiring is working.

@chernomor
Copy link
Contributor

@riaqn

  1. version-m - it's bug, it should be version (in fact in lock-file cortex-m has version 0.5.8)
  2. i try to migrate to stm32f1xx-hal, but not successful. So i still use old version.

I will try to make an example and check it in some days.

@riaqn
Copy link
Author

riaqn commented Jun 7, 2019

OK I got it working. Obviously I still need the clock trick, as @chernomor mentioned.

   let clocks = rcc.cfgr.sysclk(64.mhz()).pclk1(32.mhz()).freeze(&mut flash.acr);

Curiously enough, I was able to get away without this in the past.

For future record, this is my Cargo.toml.

[package]
authors = ["Zesen Qian <github@riaqn.org>"]
edition = "2018"
readme = "README.md"
name = "dollhouse"
version = "0.1.0"

[dependencies]
cortex-m = "0.6.0"
cortex-m-rt = "0.6.8"
panic-semihosting = "0.5.2"
onewire = "0.3.10"

[dependencies.stm32f1xx-hal]
version = "0.3.0"
features = ["stm32f103", "rt"]

[dependencies.arrayvec]
version = "0.4.10"
default-features = false
features = []

[profile.release]
codegen-units = 1 # better optimizations
debug = true # symbols are nice and they don't increase the size on Flash
opt-level = 2
lto = true # better optimizations

this is the main.rs

#![no_std]
#![no_main]

extern crate panic_semihosting;

use arrayvec::ArrayVec;

use onewire::{
    OneWire,
    DeviceSearch,
    ds18b20,
};

use self::ds18b20::{DS18B20, split_temp};

use stm32f1xx_hal::{
    prelude::*,
    pac,
    delay,
};
use cortex_m_rt::entry;

#[entry]
fn main() -> ! {
    let cp = cortex_m::Peripherals::take().unwrap();
    let dp = pac::Peripherals::take().unwrap();
    let mut flash = dp.FLASH.constrain();
    let mut rcc = dp.RCC.constrain();

    let clocks = rcc.cfgr.sysclk(64.mhz()).pclk1(32.mhz()).freeze(&mut flash.acr);
    let mut gpiob = dp.GPIOB.split(&mut rcc.apb2);
    let mut gpioc = dp.GPIOC.split(&mut rcc.apb2);

    let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
    
    let mut delay = delay::Delay::new(cp.SYST, clocks);
    
    let mut one = gpiob
        .pb9
        .into_open_drain_output(&mut gpiob.crh)
        .downgrade();

    let mut wire = OneWire::new(&mut one, false);

    if wire.reset(&mut delay).is_err() {
        panic!("missing pullup or error on line");
    }

    const N_SENS : usize = 2;
    const TARGET : f32 = 30.0;
    let mut vec = ArrayVec::<[_; N_SENS]>::new();

    // search for devices
    let mut search = DeviceSearch::new();
    while let Some(device) = wire.search_next(&mut search, &mut delay).unwrap() {
        match device.address[0] {
            ds18b20::FAMILY_CODE => {
                vec.push(DS18B20::new(device).unwrap());
            },
            _ => {
                panic!("unrecognized device {}", device);
            }
        }
    }

    assert_eq!(vec.len(), N_SENS);

    loop {
        let mut switch = true;
        for i in 0..vec.len() {
                // request sensor to measure temperature
                let resolution = vec[i].measure_temperature(&mut wire, &mut delay).unwrap();
                
                // wait for compeltion, depends on resolution 
                delay.delay_ms(resolution.time_ms());
                
                // read temperature
                let temperature = vec[i].read_temperature(&mut wire, &mut delay).unwrap();

                let (d, f) = split_temp(temperature);
                let t : f32 = d as f32 + f as f32 / 10000 as f32;
                if t >= TARGET {
                    switch = false;
                }
        }
        if switch {
            led.set_high();
        } else {
            led.set_low();
        }
    }
}

@riaqn riaqn closed this as completed Jun 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants