Pages: [1] 2   Go Down
Author Topic: DuinOS + Arduino 1.03 + DS18B20  (Read 859 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello.

In my small project I'm using DuinOS(downloaded here https://github.com/carlosdelfino/DuinOS), Arduino(Uno) v.1.03 and DS18B20. And here is the place, where problems have come from... I've created a separated task for the temperature reading and I've copied the code from the OneWire examples into the task and modified it a bit to use a lcd -screen, instead of Serial monitor. After that, I've built the app and run it... So, getting to the point, the app gets stuck here(or hung, whatever you'd like more =) ):

Code:
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }

lcd.print("WE ARE HERE");           //THIS LINE WILL NEVER BE REACHED



After all, Arduino get stuck too. In other words, the data cannot be read or written into the device or from the device.

Does anybody know, how could this problem to be solved?  

Thank you beforehand for your answers.
« Last Edit: February 05, 2013, 03:36:35 pm by dminik » Logged

Queens, New York
Offline Offline
Faraday Member
**
Karma: 98
Posts: 3576
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

We need the full code.
Logged

Created Libraries:
NPV2 (NewPasswordV2),  TFT_Extension, OneWireKeypad, SerialServo.
Will provide libraries if asked in PM or forum.

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for your answer.

Here is the code of the small project:
Code:
#include <LiquidCrystal.h>
#include <OneWire.h>

#include <string.h>
#include <stdio.h>

#define LENGTH 32

LiquidCrystal lcd(8, 11, 9, 4, 5, 6, 7);
OneWire ds(4);

int inputBtn = 0;
char buffer[LENGTH];
enum States{Stop = 0, Start} states;

taskLoop(ReadButton)
{
  checkBtn();  
  delay(50);
}

taskLoop(ReadTemperature)
{
  if(states == Start)
  {
     byte i;
byte present = 0;
   byte type_s;
   byte data[12];
   byte addr[8];
   float celsius;
  
  if ( !ds.search(addr)) {
    lcd.clear();
lcd.print("No more addresses");
    ds.reset_search();
    delay(250);
    return;
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
lcd.clear();
      lcd.print("CRC is not valid!");
      return;
  }
 
  // the first ROM byte indicates which chip
  //we don't need it. Since the device's type_s = 0
  switch (addr[0]) {
    case 0x10:
     //old DS1820
      type_s = 1;
      break;
    case 0x28:
      //Chip = DS18B20;
      type_s = 0;
      break;
    case 0x22:
      //Chip = DS1822;
      type_s = 0;
      break;
    default:
      return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }        
//The app will never pass here

  // convert the data to actual temperature

  unsigned int raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // count remain gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
    // default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  ToString(celsius);
  lcd.clear();
  lcd.print(buffer);
  }
  delay(100);
}

void ToString(float num)
{
  memset(buffer, 0, LENGTH);
  sprintf(buffer, "%.2f", num);
}

void checkBtn()
{
  inputBtn = analogRead(0);
  if(inputBtn >= 710 && inputBtn < 900)
  {
    states = Start;
  }  
  else if(inputBtn >= 470 && inputBtn < 700)
  {
    states = Stop;
    lcd.clear();
    lcd.print("Stopped");
  }
}

void setup()
{
  lcd.begin(16, 2);
  lcd.home();
  lcd.print("Greetings!");
  createTaskLoop(ReadButton, NORMAL_PRIORITY);
  createTaskLoop(ReadTemperature, NORMAL_PRIORITY);
}

void loop()
{
 //TO DO: add some code
}


« Last Edit: February 06, 2013, 01:57:59 am by dminik » Logged

Queens, New York
Offline Offline
Faraday Member
**
Karma: 98
Posts: 3576
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Was this an example, or did you make this yourself?

Does your code know to go to,
createTaskLoop(ReadButton, NORMAL_PRIORITY);
createTaskLoop(ReadTemperature, NORMAL_PRIORITY);

and not,
TaskLoop(ReadButton, NORMAL_PRIORITY);
TaskLoop(ReadTemperature, NORMAL_PRIORITY);

What is the code doing?
Logged

Created Libraries:
NPV2 (NewPasswordV2),  TFT_Extension, OneWireKeypad, SerialServo.
Will provide libraries if asked in PM or forum.

Offline Offline
Edison Member
*
Karma: 48
Posts: 1616
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
sprintf(buffer, "%.2f", num);
AFAIK sprintf can't do floating point conversions so this probably puts a null in the buffer and you end up displaying nothing.
So, what exactly is printed on the Serial monitor?

Pete
Logged

Where are the Nick Gammons of yesteryear?

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Was this an example, or did you make this yourself?

Does your code know to go to,
createTaskLoop(ReadButton, NORMAL_PRIORITY);
createTaskLoop(ReadTemperature, NORMAL_PRIORITY);

and not,
TaskLoop(ReadButton, NORMAL_PRIORITY);
TaskLoop(ReadTemperature, NORMAL_PRIORITY);

What is the code doing?

Basically it's the same code as was behind the link I published first. Arduino is waiting for the user input. Then the reading starting. So, the app just read the sensor's value, convert it to the temperature and print it to the LCD -screen. Also, there is a stop button. Thus user can stop reading whenever she wants.
About createTaskLoop(...) - yes, you are right, probably I didn't copy it from the project file well. It was a ready example, which is shipped with a current version of the OneWire -library. In the original example there is no any tasks either lcd-screens or buttons. Only a serial monitor. But, if you will try to compile it and run, you'll face the same problem.

p.s. I'm sorry for the bad explanation of the problem.
« Last Edit: February 05, 2013, 03:38:43 pm by dminik » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
sprintf(buffer, "%.2f", num);
AFAIK sprintf can't do floating point conversions so this probably puts a null in the buffer and you end up displaying nothing.
So, what exactly is printed on the Serial monitor?

Pete


Sorry, for the bad explanation. Serial monitor doesn't print anything. I changed the example and replaced the Serial.print with lcd.print. Basically it does the same work - prints the data out. But I've tried both serial and lcd. Neither of them will print anything after the sensor reading was done.
But sprintf is a common C function which was used for decades and everything worked before, even with a float -type.
Logged

Offline Offline
Edison Member
*
Karma: 48
Posts: 1616
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But sprintf is a common C function which was used for decades and everything worked before, even with a float -type.
If you say so, but try this sketch.
Code:
void setup(void)
{
  Serial.begin(9600);
  char oline[32];
  sprintf(oline,"float '%6.2f'",6.231);
  Serial.println(oline);
}

void loop(void){}

Pete
Logged

Where are the Nick Gammons of yesteryear?

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But sprintf is a common C function which was used for decades and everything worked before, even with a float -type.
If you say so, but try this sketch.
Code:
void setup(void)
{
  Serial.begin(9600);
  char oline[32];
  sprintf(oline,"float '%6.2f'",6.231);
  Serial.println(oline);
}

void loop(void){}

Pete


OK, I admit, may be Arduino handle this function in a different way. Also, I googled recently a topic about problem you mentioned. But the problem is not there at all. Arduino doesn't even pass there. It will get stuck or hung right after the data reading.

for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data = ds.read();
  }

//Program will not pass here.

So this code:

unsigned int raw = (data[1] << smiley-cool | data[0];
  if (type_s) { ......................

will not be executed. So I know the exact place where the app gets stuck. And I suspect the data reading.
Logged

Offline Offline
Edison Member
*
Karma: 48
Posts: 1616
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So I know the exact place where the app gets stuck
It doesn't print anything at that point so how can you know that it gets stuck there?
And it would help if you post the code that you are talking about, all of it.
BTW. It would be better if you use Serial.println for debugging messages rather than LCD.print just to be sure that there's no problem with the LCD.

Pete
Logged

Where are the Nick Gammons of yesteryear?

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for your answer.
ABout printing, Serial Monitor doesn't print any information after the attempt to read bytes from the device.
Here is the code I'm using now for testing(It's not that good as I want to, but for the testing purposes it works well):

Code:
#include <LiquidCrystal.h>
#include <OneWire.h>

#include <string.h>
#include <stdio.h>

#define LENGTH 32

LiquidCrystal lcd(8, 11, 9, 4, 5, 6, 7);
OneWire ds(4);

int inputBtn = 0;
char buffer[LENGTH];
enum States{Stop = 0, Start} states;

taskLoop(ReadButton)
{
  checkBtn(); 
  delay(50);
}

taskLoop(ReadTemperature)
{
  if(states == Start)
  {
     byte i;
byte present = 0;
   byte type_s;
   byte data[12];
   byte addr[8];
   float celsius;
 
  if ( !ds.search(addr)) {
    lcd.clear();
lcd.print("No more addresses");
    ds.reset_search();
    delay(250);
    return;
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
lcd.clear();
      lcd.print("CRC is not valid!");
      return;
  }
 
  // the first ROM byte indicates which chip
  //we don't need it. Since the device's type_s = 0
  switch (addr[0]) {
    case 0x10:
     //old DS1820
      type_s = 1;
      break;
    case 0x28:
      //Chip = DS18B20;
      type_s = 0;
      break;
    case 0x22:
      //Chip = DS1822;
      type_s = 0;
      break;
    default:
      return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
 
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
 
  present = ds.reset();
  ds.select(addr);   
  ds.write(0xBE);         // Read Scratchpad

  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }       
//The app will never pass here

  // convert the data to actual temperature

  unsigned int raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // count remain gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
    // default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  ToString(celsius);
  lcd.clear();
  lcd.print(buffer);
  }
  delay(100);
}

void ToString(float num)
{
  memset(buffer, 0, LENGTH);
  sprintf(buffer, "%.2f", num);
}

void checkBtn()
{
  inputBtn = analogRead(0);
  if(inputBtn >= 710 && inputBtn < 900)
  {
    states = Start;
  } 
  else if(inputBtn >= 470 && inputBtn < 700)
  {
    states = Stop;
    lcd.clear();
    lcd.print("Stopped");
  }
}

void setup()
{
  lcd.begin(16, 2);
  lcd.home();
  lcd.print("Greetings!");
  createTaskLoop(ReadButton, NORMAL_PRIORITY);
  createTaskLoop(ReadTemperature, NORMAL_PRIORITY);
}

void loop()
{
 //TO DO: add some code
}


How could I know the Arduino gets stuck there? I put the lcd.print("TEST"); delay(5000); before bytes reading and lcd.print("ABC"); delay(5000); after reading. So, the first one will be printed. But the second one will not be printed, even after 5 seconds of waiting. Also I've tried to do it without delays. Result is the same. I've tried to do it with a serial monitor - same result as before.

I really appreciate, if somebody will show me the working code for the same configuration: Arduino Uno 1.03 + DS18B20 + DuinOS v. 0.4 alpha.

I know, Arduino all alone works perfectly with onewire, but I need a bit more for my small project.
Logged

Offline Offline
Edison Member
*
Karma: 48
Posts: 1616
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I know, Arduino all alone works perfectly with onewire
Have you tried using DuinOS with *only* the DS18B20? Let's make sure that DuinOS and DS18B20 will even work together when there's nothing else that might get in the way.

Pete
Logged

Where are the Nick Gammons of yesteryear?

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I didn't, but let's say, this one: DuinOS + Arduino 0023 + DS18B20 will work.
Logged

Offline Offline
Edison Member
*
Karma: 48
Posts: 1616
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
let's say, this one: DuinOS + Arduino 0023 + DS18B20 will work
"will" work or "does" work?

You need to do some tests to eliminate potential sources of problems/conflicts. So, can you get DuinOS + Arduino 1.03 to work with only the DS18B20?

Pete
Logged

Where are the Nick Gammons of yesteryear?

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
let's say, this one: DuinOS + Arduino 0023 + DS18B20 will work
"will" work or "does" work?

You need to do some tests to eliminate potential sources of problems/conflicts. So, can you get DuinOS + Arduino 1.03 to work with only the DS18B20?

Pete

I meant it does work.

I can't get work DuinOS + Arduino 1.03 with only DS18B20. I've already tried to treat it as parasite device with all resets included according to this one http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf. I tried to change resistance - nothing.
Logged

Pages: [1] 2   Go Up
Jump to: