Pages: 1 2 3 [4] 5   Go Down
Author Topic: [SOLVED] 18B20 timing problem  (Read 6292 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5790
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

all my code derived from arduinix project, the code is very long if you want go to the official site.

it is a clock that need BCD , the BCD value need to bo always present, example if i use a delay of 1000ms, it block the BCD routine, and the display is off.

My idea is, but no people explain me if it is true or not, that during our famous 28ms the TEMP variable is Empty or Not Accessible. It is true ?

It is a basic question, but hard for me because I came from the electronic world, not sw.
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Don't know the Arduinix project, if you want people to look there you might provide an URL or so.

Quote
it is a clock that need BCD
What is BCD ? Binary Coded Decimal?


Quote
My idea is, but no people explain me if it is true or not, that during our famous 28ms the TEMP variable is Empty or Not Accessible. It is true ?
not true. (not seen the code so all disclaimers apply smiley-wink

<explanation>
A variable will keep its value until it is changed OR goes out of scope.
A variable can't be empty, technically speaking there is allways content, defined or undefined.

Software takes time to execute, every single statement takes time.
The Arduino can only do one thread at the time (and IRQ's )

So the statement
TEMP = getTempCByIndex(0);
will take 28 ms, but only in the last microsecond the value of TEMP will change.
When the processor is executing getTempCByINdex(), the variable TEMP can not be accessed by other routines except for interrupt routines as the Arduino is single threaded.
</explanation>

Hope this explanation is clear to you.

Q: How often do you refresh your display?
You only need to refresh the parts that have changed!
So the whole 28ms the "old" value of TEMP should be left unchanged on the display, just like in the other 750 ms.

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5790
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

this is the arduinix code that i used, http://arduinix.com/Main/Code/Arduinix-6bulb-clock-demo.txt

the display is updated every milliseconds by bcd (yes binary coded decimal)

in your explanation:
 "executing getTempCByINdex(), the variable TEMP can not be accessed by other routines"

-- this means that it is not possible access TEMP for 28ms or for 1 microsecond ?

thanks
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
in your explanation:
 "executing getTempCByINdex(), the variable TEMP can not be accessed by other routines"

-- this means that it is not possible access TEMP for 28ms or for 1 microsecond ?
28 milliseconds.


I ran the Arduinix code (don't have nixies ) and the display is written approx every 10 milliseconds, so to calculate and display the time 10 millis is needed, That means that the display does not go off if you are calculating...

  Can you add   delay(50);   before this line   DisplayNumberString( NumberArray );  in loop();  // at the end of the sketch

Does that still display time correctly?

If so the delay for getTempCByIndex() should work.

Rob


Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5790
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

NO
the time is blocked, blinking.

so this demonstrate that my diagnosis is good ? Is the 28ms the problem because during this 28ms the variable TEMP it is not accessible, are you agree ?

option 1: decrease the gettemo needed time (no other sw solution is possible because the 28ms block the bcd calculation)
option 2: hardware solution, external latch ?
option 3: change the sensor, with one analogic like lm35 ? (analogic sensor do not have long calculating time right ? the value it is always present)
  
« Last Edit: August 13, 2011, 03:37:55 pm by Testato » Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
so this demonstrate that my diagnosis is good ?

No, it shows that the Arduinix sketch need to refresh very often to keep the nixies displaying constantly, that is the cause. By lowering the value of the inserted delay() from 50 to 0 in a few steps you can find out how much time you have to do calculations for TEMP.

Try the following values for delay 50,40,30,25,20,15,10,5 and report what delay is acceptable and what not.


Current the math for the time is approx 10 millis which shows no dimming. I have not investigated WHY nixies in this Arduinix sketch behave that way, maybe due to multiplexing? Don't know. There is a delay(3) in the code that must be executed otherwise they will not light up. (change this to 5?  10? what happens)

Quote
Is the 28ms the problem because during this 28ms the variable TEMP it is not accessible, are you agree ?
No I do not agree. The main cause is the Arduinix code

Again: The variable TEMP is perfectly accessible, that is not the point. The point is the Arduino can only do one thing at the time, it is single tasking at best. It can't keep displaying 100(?) times per second a string and do one calculation that takes 28 millisecond.

Solution: Don't use the Dallas Temperature Control Library. Develop code (all needed steps are available in the DTCLib) in which you have split this 28ms function in smaller chunks, chunks of max 10 ms. and execute these smaller chunks between rewrites

do part 1 ; display ;l do part 2 ; display; do p[art 3 ; display; etc.






Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 202
Posts: 8719
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The way to fix the problem is to make the nixie tube update code interrupt driven.  Just set up TimerCounter2 to interrupt every few milliseconds and each interrupt, update a digit.  Then you can change the digits any time.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Perfect idea John!!

why didn't I think of that smiley-wink  this also means a serious rewrite.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5790
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

x rob: i'm agree with you,
when i tell "the problem is 28ms" i know that it is only "one side" of problem.
the very-speedy refresh of display is the "other side".
the important is that now, thanks to you and other, i know which is the problem.
understand that arduino is single task it is very important for me.


if i understand your idea is: the gettempbyindex command is created by more single command, i must use all of them mixed with display visualization subroutine.

x john: your tips is too mutch for me, i need study what means code interrupt driven. do you have a link ? i'm new to the programming side, i came from electronic side of game smiley


thanks
« Last Edit: August 16, 2011, 11:22:48 am by Testato » Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Startpoint for IRQ's - http://www.arduino.cc/en/Reference/AttachInterrupt -
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 202
Posts: 8719
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Hmmm...  That page for attachInterrupt() only talks about EXTERNAL interrupts.  Does it not deal with timer/counter interrupts?
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oops, maybe this playground article is better ! - http://www.arduino.cc/playground/Code/Timer1 - ?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5790
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

very interesting, i tried 2 example for interrupt hardware, and it work, one for led and one for bump switch.
I will read the other info on timer interrupt.

a basic question, when the interrupt is called it block the mail loop and start the execution of ISR, right ?

So it is always single thread, if i put in ISR "temp=gettempbyindex" this need 28ms, and the main loop is blocked for 28ms.
It is right ?

 
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
a basic question, when the interrupt is called it block the mail loop and start the execution of ISR, right ?
Right

Quote
So it is always single thread, if i put in ISR "temp=gettempbyindex" this need 28ms, and the main loop is blocked for 28ms.
It is right ?
Right

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5790
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Semisolved smiley
I found a code that read the sensor without library, no onewire no dallas.
whit a fantastic response time  of 5ms.

i write semisolved because 15ms (5sensor+10display) create flickering, i working on it.
this is code
Code:
/*ReadDS18B20
ver: 6 Jly 2010
THIS IS A FIRST DRAFT.... WORKS, but scheduled for overhaul.


Simple, simple test of reading DS18B20
connected to nuelectronics.com datalogging shield.

See...

http://sheepdogguides.com/arduino/ar3ne1tt.htm

... for explanation of this code.

Code lightly adapted from code from nuelectronics.com*/

#define TEMP_PIN  14 //See Note 1, sheepdogguides..ar3ne1tt.htm

void OneWireReset(int Pin);//See Note 2
void OneWireOutByte(int Pin, byte d);
byte OneWireInByte(int Pin);

void setup() {
    digitalWrite(TEMP_PIN, LOW);
    pinMode(TEMP_PIN, INPUT);      // sets the digital pin as input (logic 1)
Serial.begin(9600);
//9600 to match the data rate being used by the
//serial monitor on my system, which is set to
//the Arduino default. (Sample code published
//by nuelectronics used a faster baud rate.)
    delay(100);
    Serial.print("temperature measurement:\n");
}

void loop(){
  int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;

  OneWireReset(TEMP_PIN);
  OneWireOutByte(TEMP_PIN, 0xcc);
  OneWireOutByte(TEMP_PIN, 0x44); // perform temperature conversion, strong pullup for one sec

  OneWireReset(TEMP_PIN);
  OneWireOutByte(TEMP_PIN, 0xcc);
  OneWireOutByte(TEMP_PIN, 0xbe);

  LowByte = OneWireInByte(TEMP_PIN);
  HighByte = OneWireInByte(TEMP_PIN);
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // test most sig bit
  if (SignBit) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

  Whole = Tc_100 / 100;  // separate off the whole and fractional portions
  Fract = Tc_100 % 100;


  if (SignBit) // If its negative
  {
     Serial.print("-");
  }
  Serial.print(Whole);
  Serial.print(".");
  if (Fract < 10)
  {
     Serial.print("0");
  }

  Serial.print(Fract);

      Serial.print("\n");
  delay(5000);      // 5 second delay.  Adjust as necessary
}

void OneWireReset(int Pin) // reset.  Should improve to act as a presence pulse
{
     digitalWrite(Pin, LOW);
     pinMode(Pin, OUTPUT); // bring low for 500 us
     delayMicroseconds(500);
     pinMode(Pin, INPUT);
     delayMicroseconds(500);
}

void OneWireOutByte(int Pin, byte d) // output byte d (least sig bit first).
{
   byte n;

   for(n=8; n!=0; n--)
   {
      if ((d & 0x01) == 1)  // test least sig bit
      {
         digitalWrite(Pin, LOW);
         pinMode(Pin, OUTPUT);
         delayMicroseconds(5);
         pinMode(Pin, INPUT);
         delayMicroseconds(60);
      }
      else
      {
         digitalWrite(Pin, LOW);
         pinMode(Pin, OUTPUT);
         delayMicroseconds(60);
         pinMode(Pin, INPUT);
      }

      d=d>>1; // now the next bit is in the least sig bit position.
   }

}

byte OneWireInByte(int Pin) // read byte, least sig byte first
{
    byte d, n, b;

    for (n=0; n<8; n++)
    {
        digitalWrite(Pin, LOW);
        pinMode(Pin, OUTPUT);
        delayMicroseconds(5);
        pinMode(Pin, INPUT);
        delayMicroseconds(5);
        b = digitalRead(Pin);
        delayMicroseconds(50);
        d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position
    }
    return(d);
}
« Last Edit: August 16, 2011, 04:12:08 pm by Testato » Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Pages: 1 2 3 [4] 5   Go Up
Jump to: