Shop OBEX P1 Docs P2 Docs Learn Events
Max 7219 7-segments and a value with a decimal point — Parallax Forums

Max 7219 7-segments and a value with a decimal point

Walter recently updated his DHT11/22 sensor object (http://obex.parallax.com/object/837) and I've been playing with it. Out of the box it shows temp and humidity on the PST.

Showing the temperature and humidity on an LCD is easy, I'm using this object for LCDs with a PCF8574 backpack:
http://obex.parallax.com/object/833
Replace the pst.str commands with lcd.str commands and It Just Works. (Thanks, JM!)

However, I also have one of those Max 7219 7-segment display sticks, and thought it would be interesting to show the temperature on it too. And here's where I'm stuck.

I can show numbers on the Max display that are generated by RCTime...

- Set registers to DECODE mode
- Extract individual digits of rctime value to a buffer
- Write the buffer to the display

But the DHT sensors return a temperature, which has a decimal in it - 68.5, etc. How do I handle extracting these digits and keeping track of the decimal? Is there an object I can check out?

Comments

  • You are going to have to parse the string.

    If you assumed (as a zeroth approximation) that the string was always four characters TU.t (that is Tens, Units, Point, tenths) you could just subtract $30 from the first character to get the value for the tens digit, same thing for the second character for the units, same thing for the fourth character for the tenths. The decimal point goes with the units or tenths, depending on whether you have right hand or left hand decimal points.

    Of course, that is an gross over-simplication because it doesn't treat the case of greater than 99.9 degrees or less than 10.0 degrees. Let alone that it could be negative.

    Another approach would be to convert the floating point to integer tenths. Then you can use integer divide and modulo to extract the digits.

    Finally, the Arduino guys have fiddled with the 7219 in more detail than I would have thought possible. There may be a specific driver for the 7219 over there (it would be in C of course).
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    I have BASIC Stamp Code that displays the time and uses the decimal point control to handle the AM/PM, time colon and ALM1/ALM2 indicators. If you're interested let me know. You might be able to use it as a reference for handling the decimal control.
  • Tom, thanks for the tips, I'll look into it.

    And Chris, please post the code, I'm sure there's something I can get out of it.
  • MJBMJB Posts: 1,235
    interrestingly Peter just posted his MAX7219 driver for Tachyon -
    might not help a lot, but here is it anyhow
    Tachyon driver for MAX7219
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2016-04-07 19:50
    Send me an email to support at parallax dot com and I will reply back with that code. The PBASIC should be easy enough to glean what you need from that. I can post the important stuff below.

    Essentially I have a section that writes the various digits to my clock display. The decimal points for the minutes are wired to the colon LEDs between the hours and minutes. So they're always going to be on. So when I write out the minutes it looks like this:
    ioByte = ioByte | DecPnt              ' Enable Decimal Point (Colon)
      GOSUB Max_Out                         ' Send To Display
    

    ioByte contains the value I am displaying and when I want the decimal point on I just OR it with DecPnt, which is a constant:
    DecPnt          CON     %10000000       ' Decimal Point
    

    You're essentially setting the high bit of the byte for that digit. Then it calls the routine that shifts the data to the MAX7219.
    Max_Out:
      SHIFTOUT DataIO, Clock, MSBFIRST, [index, ioByte]
      PULSOUT MAX7219, 5                    ' Latch Data
      RETURN
    

    When you want to programmatically turn on the decimal point you can just do the OR when the right condition is met. For example, on mine if the ALM1 is set then the decimal point is turned on for that digit as shown below.
      index = 6                             ' Set Sixth Digit (DP)
      ioByte = Blank                        ' Pre-Blank
      IF a1Status = 1 THEN ioByte = ioByte | DecPnt ' Enable DP If 1
      GOSUB Max_Out                         ' Send To Display
    

    Here I am making sure there is no number, and that the decimal point only comes on if a1Status is equal to 1.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2016-04-07 23:38
    MJB wrote: »
    interrestingly Peter just posted his MAX7219 driver for Tachyon -
    might not help a lot, but here is it anyhow
    Tachyon driver for MAX7219

    This thread reminded me about the 7219 driver so I got sidetracked and did it even though I didn't have hardware!

    To interface the DHT21/22 sensor to the display in Tachyon could be as simple as:
    #P4 DHT MAX7219 PRINT SPACE PRINT CON

    Which would execute immediately reading the sensor (on pin 4) and display the temperature and humidity on the 7-segment display. Building fancier definitions takes less than a minute with instant results!

    btw, decimal points are handled automatically when they are encountered in a character stream, so PRINT" 12.34" will produce a correct display.
  • Here's my MAX7219 object if you think it will help.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2016-04-08 04:05
    Oh yeah, and I've just updated my driver to handle full ASCII characters and symbols too. Now you can say "PRINT" PROP.LED7" and that will be very readable in 8-digits.
    MAX7219 CR PRINT" PROP.LED7" CON  ok
    ledbuf 10 DUMP 
    0000_4560:   08 73 50 5C  F3 38 79 5E   07 00 29 73  0B A0 11 A0   .sP\.8y^..)s.... ok
    
  • Peter, thanks for the info. However I'm still learning Spin, so Forth is not gonna happen right now. And Jonny, I'm already using the version of your code from the OBEX, this one seems to be a slight formatting update.

    I realize I may not have asked the right question. Here's the key method:
    Pub DHT_read_MAX7219
    
    repeat
        readStatus := -1
    
        DHT.DHTnn_Read 
    
        repeat until ReadStatus => 0
    
        if ReadStatus == 1
          temperature := f.FMul(temperature, 9.0)    ' Convert °C to °F
          temperature := f.FDiv(temperature, 5.0)
          temperature := f.FAdd(temperature, 32.0)
    
          serial.str(fp.FloatToString(temperature))
          serial.str(@fahr)
          serial.str(@space)
    
          temperature := (fp.FloatToString(temperature))   
    
          leds.out(leds#DECODE, %00011111)
       
    '      leds.extract(@digitsbuf, 54321)  ' Test value
    
          leds.extract(@digitsbuf, temperature)
          
          leds.write_buf(@digitsbuf, 8, 1)
    
          serial.str(temperature)
               
    '      serial.str(fp.FloatToString(humidity))
    '      serial.str(@percent)
    
          serial.str(@crlf)
    
        else
          serial.str(@invalid)
          serial.str(@crlf)
    

    This displays the result of the DHT reading on both the PST and the Max7219 stick. For example, the PST will show 70.52, while the Max will show 04376. So there's some conversion of the FloatToString result that needs to happen to format things for the buffer sent to the Max stick.

    I've also attached the entire project archive if the code above isn't enough info.

    Of course, there's a little voice in the back of my head saying, "It works on an LCD, why are you doing this?!" Right now I'm ignoring it because this is interesting.

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2016-04-08 08:00
    Jeff Haas wrote: »
    Peter, thanks for the info. However I'm still learning Spin, so Forth is not gonna happen right now.

    Like I always say, when is a good time? Considering that it is so easy to get it all running too.

    However why are you using floating point??? All you need to do is to scale the reading and insert your decimal point as needed. If JM's driver is doing FP then change it. FP seems to me to be lazy programming style inherited from PC programming where FP is free but the Prop can't even multiply two integers without software. I've never ever in all my programming experience ever needed to use FP, just plain old scaled integers.

    P.S. as to the voice in your head it's always good to know when to ignore it when it is trying to be sensible.
  • MJBMJB Posts: 1,235
    Jeff Haas wrote: »
    However I'm still learning Spin, so Forth is not gonna happen right now.
    Just when I had discovered the Propeller and started reading the forum Peter started with his Tachyon. So I basically skipped SPIN (if you know any other programming language reading it is not too difficult except for some strange |< and things ;-)
    and directly moved to Tachyon and never regretted it.
    Actually in reading the Tachyon kernel source code (since at that time there was almost no documentation - not like today with glossary, intoduction and encyclopedia of Tachyon all around and lot's of code as well) I learnt PASM as well.
    So life is possible without SPIN and C ;-)
    give Tachyon a try and have interactive fun
    Markus
  • MJBMJB Posts: 1,235
    edited 2016-04-08 11:31
    MJB wrote: »
    interrestingly Peter just posted his MAX7219 driver for Tachyon -
    might not help a lot, but here is it anyhow
    Tachyon driver for MAX7219

    This thread reminded me about the 7219 driver so I got sidetracked and did it even though I didn't have hardware!

    To interface the DHT21/22 sensor to the display in Tachyon could be as simple as:
    #P4 DHT MAX7219 PRINT SPACE PRINT CON

    Which would execute immediately reading the sensor (on pin 4) and display the temperature and humidity on the 7-segment display. Building fancier definitions takes less than a minute with instant results!

    btw, decimal points are handled automatically when they are encountered in a character stream, so PRINT" 12.34" will produce a correct display.
    @Peter
    according to the DHT22 datasheet
    DHT22 send out higher data bit firstly!
    DATA=8 bit integral RH data+8 bit decimal RH data+8 bit integral T data+8 bit decimal T data+8 bit check-sum
    If the data transmission is right, check-sum should be the last 8 bit of "8 bit integral RH data+8 bit decimal RH
    data+8 bit integral T data+8 bit decimal T data".
    and checking your latest code (my Arduino visitor had a DHT11 which provides no decimals that I interfaced for him to Tachyon a few days ago ..)
    I thought printing would be:
    #P4 DHT MAX7219 W>B  PRINT "." EMIT PRINT SPACE W>B  PRINT "." EMIT PRINT CON
    
    to handle the integer / fraction part of the result and printing with decimal point.
    Better might be a .DHT22
    pub .DHT22 DHT W>B  PRINT "." EMIT PRINT SPACE W>B  PRINT "." EMIT PRINT ;
    \ and then just
    MAX7219 #P4 .DHT22 CON
    

    @Jeff - see? simple !
  • MJBMJB Posts: 1,235
    video of Tachyon MAX7219 7-segment driver
    forums.parallax.com/discussion/comment/1371244/#Comment_1371244
Sign In or Register to comment.