Jump to content
43oh

Digital Picture Frame Thermometer


Recommended Posts

A digital picture frame is used as a thermometer. Pictures representing a range of temperature are displayed by simulating the press of the next or previous buttons on the picture frame. This makes the project very simple by avoiding having to drive the LCD directly with the microcontroller. The high resolution backlit display is much more readable than the usual reflective monochrome LCD thermometer and the pictures can be as simple or fancy as you want.

 

A Maxim DS1820, DS18S20, DS18B20 or DS1822 temperature sensor can be used. The code will adapt to any of these models. The DS18B20 is recommend.

 

The main code is written in C and uses assembly libraries for speed and precision timing. All the assembly code has been posted previously: Dallas/Maxim one wire library, Fast itoa() for CCS, and Compact serial tx

 

Typical wiring

post-2341-135135513266_thumb.png

 

Simple text display on picture frame. The text color changes with temperature (blue -> green -> yellow -> red)

post-2341-135135513283_thumb.jpg

 

Serial output shows Deg C, Deg F, Displayed temperature, and up/down actions.

post-2341-135135513277_thumb.png

 

Excerpt from main.c showing how the temperature sensor is read and the display is updated when necessary. Hysteresis is used to ensure a stable display.

   do {                                            //
       puth(owrst());                              // Reset
       puth(owwb(0x33));                           // Read ROM
       puts("\r\n");                               //
   } while(!read_block(id, 9));                    // Read ID and serial
   show_block(id, 8);                              //
                                                   //
   for(; {                                       //
       print_temp(tc);                             // Show Deg C on terminal
       print_temp(tf);                             // Show Deg F on terminal
       itoa(display, s); puts(s);                  // Show displayed temperature on terminal
                                                   //
       delta = tf - (display << 4);                // Difference between measured and displayed
                                                   //
       if(delta > hyst) {                          // - Above displayed
           ++display;                              // Increment displayed
           pb(1 << up_pin);                        // Push up button
           puts(" Up");                            //
       } else if(-delta > hyst) {                  // - Below displayed
           --display;                              // Decrement displayed
           pb(1 << down_pin);                      // Push down button
           puts(" Down");                          //
       }                                           //
       puts("\r\n");                               //
                                                   //
       tc = tf = error_temp << 4;                  // Default to error temperature
       if(!owrst()) continue;                      // Convert
       if(owww(0x44CC) != 0x44CC) continue;        //  
       delay_ms(800);                              // Wait for conversion to complete
       if(!owrst()) continue;                      // Read temperature
       if(owww(0xBECC) != 0xBECC) continue;        //
       if(read_block(b, 9)) continue;              //
                                                   //
       tc = b[1]; tc <<= 8; tc |= b[0];            // All
       if(id[0] == 0x10) {                         // DS1820 and DS18S20 only
           tc <<= 3;                               // Convert 1/2 C resolution to 1/16 C resolution
           if(b[7] == 16) {                        // DS18S20 12 bit only (divisor of DS1820 is not fixed at 16)
               tc &= 0xFFF0; tc = tc + 12 - b[6];  // Update with residual count for 1/16 C resolution
           }                                       //
       }                                           //
       tf = ((tc + (tc << 3)) + 2562 ) / 5;        // Convert deg C to deg F
   }

 

Complete code

dpft.zip

Link to post
Share on other sites
  • 3 months later...

Hi,

I'm trying to us a temperature sensor with my uC, I tried to use your code, but unfortunately you are using assembler incompatible with msp430-gcc.

I did few changes that were obvious, and the code almost compiles (itoa compiles fine), I'm left with two problems:

serial.asm:

37: or #0x0300, R12 ; Stop bit(s)

serial.S:37: Error: unknown opcode `or'

 

With this one I looked at the instruction set and I don't see "or" in it, there is only AND and XOR. Is it replaced in the background for other commands?

I'll have to try to replace it with XORs and AND probably.

 

dow.asm:

125: cmp R13, 0(SP) ; Compare bit count

dow.S:125: Error: unknown operator 0(SP). Did you mean X(Rn) or #[hl][hl][oi](CONST) ?

 

As for the last one I have no idea why it doesn't work, moreover if I provide this command on "mspgcc sourceforge net assemble.html" then it translates to some hex does.

 

Do you have some hints how could I make it work?

 

Thanks

Link to post
Share on other sites
I did few changes that were obvious, and the code almost compiles (itoa compiles fine), I'm left with two problems:

serial.asm:

37: or #0x0300, R12 ; Stop bit(s)

serial.S:37: Error: unknown opcode `or'

 

Use the ior operation (inclusive or); gas doesn't recognize or as an alias.

 

dow.asm:

125: cmp R13, 0(SP) ; Compare bit count

dow.S:125: Error: unknown operator 0(SP). Did you mean X(Rn) or #[hl][hl][oi](CONST) ?

Use r2 for SP. gas doesn't recognize the alias for the stack pointer.

Link to post
Share on other sites
I did few changes that were obvious, and the code almost compiles (itoa compiles fine), I'm left with two problems:

 

serial.asm:

37:             or      #0x0300, R12        ; Stop bit(s)
serial.S:37: Error: unknown opcode `or'

Do you have some hints how could I make it work?

 

I had already fixed up the serial.asm here:

http://www.43oh.com/forum/viewtopic.php?f=10&t=1727#p12116

 

there are some hints on that post regarding what needs to be changed.

 

-rick

Link to post
Share on other sites
I did few changes that were obvious, and the code almost compiles (itoa compiles fine), I'm left with two problems:

serial.asm:

37: or #0x0300, R12 ; Stop bit(s)

serial.S:37: Error: unknown opcode `or'

Use the ior operation (inclusive or); gas doesn't recognize or as an alias.

 

'ior' doesn't seem to be in the 20110706 LTS version.

for this line of code I get:

 

...
ior     #0x0300, ARG1       ; Add Stop bit(s) to tx char
...

sw_serial.S:162: Error: unknown opcode `ior'

 

In the code I ported before I used BIS instead of OR. Is 'IOR' available in some upcoming release?

Is it any different than using a BIS?

 

-rick

Link to post
Share on other sites

Thank you for the quick responses. :)

I wouldn't guessed the change for R12-R15 to R15-R12 :)

Besides the changes that you described I only had to unroll loops (.loop and .endloop) in itoa.asm/itoa.S (I haven't found any replacement for it in gnu asm).

Now the code compiles and links fine, I'll post the changed files as soon as I'll have a chance to test it on my launchpad.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...