Shop OBEX P1 Docs P2 Docs Learn Events
Old Newbee needs program checked. — Parallax Forums

Old Newbee needs program checked.

IroneIrone Posts: 116
edited 2014-01-03 14:06 in BASIC Stamp
Hello,

My farmer friend wants to feed his animals with barley sprouts rather than just plain barley. He is going to make a room with humidity around 66% to grow sprouts in containers over a seven day period. This way he will have several containers full of fully sprouted barley every day to feed his livestock. His farm has natural gas for inside temperature so he asked me for some way to control the humidity in this room. It needs to keep the humidity correct but will be cheaper for him if we can also use a fan. If the outside humidity can be drawn in if the temperature is close and the humidity is less-more than is needed whichever is required. My program is passes the "tokenize" but that does not mean it works! The numbers can be easily changed for a wider tolerance if needed. Here is my program:
' {$STAMP BS2}
' {$PBASIC 2.5}
'Humidity Sensor HS1101
'Temperature Sensor DS1620
'Checking Humidity and Comparing Temperature Inside and Outside to Control with
'Either a Fan, Humidifier or a Humiditor

'---------------Controls----------------------------------------------------

Fan       PIN 5
Hum       PIN 6
DeHum     PIN 7

'---------------Variables---------------------------------------------------

OutTemp     VAR Byte
InTemp      VAR Byte

OutHum      VAR Word
InHum       VAR Word

'--------[ Initializations ]------------------------------------------------
' Note: DS1620 has been preprogrammed for mode 2.
' If not, uncomment the instructions on the next two lines on the first RUN
' HIGH 13: SHIFTOUT 15,14,[12,2]: LOW 13
' HIGH 10: SHIFTOUT 12,11,[12,2]: LOW 10

FREQOUT 0, 20, 3800                              ' Beep to signal that it is running.
HIGH 13                                          ' Select the DS1620.
SHIFTOUT 15, 14, LSBFIRST, [238]                 ' Send the "start conversions" command.
LOW 13                                           ' Wait until called for.

FREQOUT 0, 20, 3800                              ' Beep to signal that it is running.
HIGH 10                                          ' Select the DS1620.
SHIFTOUT 12, 11, LSBFIRST, [238]                 ' Send the "start conversions" command.
LOW 13                                           ' Wait until called for.
'--------------Program------------------------------------------------------
Main:

  HIGH 4                                         ' Start the 555 timer
  COUNT 3, 1000, InHum                           ' Read the inside Humidity
  LOW 4                                          ' Stop the 555 timer

  HIGH 2                                         ' Start the 555 timer
  COUNT 1, 1000, OutHum                          ' Read the outside Humidity
  LOW 2                                          ' Stop the 555 timer

  IF (InHum >=6468) AND (InHum =<6626) THEN      ' If InHum is less than 70% and higher than 58%
  GOSUB Main                                     ' Do it again
  ENDIF
  IF InHum <6468 OR InHum >6626 THEN             ' If InHum is higher than 70% or less than 58%
  GOSUB OutsideHumidity                          ' Go to OutsideHumidity
  ENDIF

OutsideHumidity:

  IF (OutHum >=6468) AND (OutHum =<6626) THEN    ' If OutHum is less than 70% and higher than 58%
  GOSUB Temperature                              ' Go to Temperature
  ELSEIF (OutHum <6468) OR (OutHum >6626) THEN   ' If OutHum is higher than 70% and lower than 58%
  GOSUB Internal_Device                          ' Go to Internal Device
  ENDIF

Temperature:
  HIGH 13                                        ' Select the DS1620 InTemp.
  SHIFTOUT 15, 14, LSBFIRST, [170]               ' Send the "get data" command.
  SHIFTIN 15, 14, LSBPRE, [InTemp]               ' Get the data.
  LOW 13                                         ' End the command.

  HIGH 10                                        ' Select the DS1620 OutTemp.
  SHIFTOUT 12, 11, LSBFIRST, [170]               ' Send the "get data" command.
  SHIFTIN 12, 11, LSBPRE, [OutTemp]              ' Get the data.
  LOW 10                                         ' End the command.

  IF OutTemp > InTemp + 12 THEN                  ' If OutTemp is over InTemp by 6 degrees C
    LOW Fan                                      ' Turn off Fan
  ELSEIF OutTemp < InTemp - 12 THEN              ' If OutTemp is under InTemp by 6 segrees C
    LOW Fan                                      ' Turn off Fan
  ELSEIF OutTemp < InTemp + 12 THEN              ' If OutTemp is under InTemp by 6 dergees C
    HIGH Fan                                     ' Turn on Fan
  ELSEIF OutTemp > InTemp - 12 THEN              ' If OutTemp is over InTemp by 6 degrees C
    HIGH Fan                                     ' Turn on Fan
  ENDIF

Internal_Device:

  IF InHum >6468 THEN                            ' If InHum is above 70%
  HIGH DeHum                                     ' Turn on Dehumidifier
  ELSEIF InHum <6574 THEN                        ' If InHum goes below 62%
  LOW DeHum                                      ' Turn off Dehumidifier
  ENDIF

  IF InHum > 6626 THEN                           ' If InHum is a below 58%
  HIGH Hum                                       ' Turn on Humidifier
  ELSEIF InHum <6535 THEN                        ' If InHum goes above 65%
  LOW Hum                                        ' Turn off Humidifier
  ENDIF

GOSUB Main

I am 66 years old so you can make any fun of me you want to, I've been through it all. I have copied some stuff and made up the rest.

Comments

  • garyggaryg Posts: 420
    edited 2013-12-28 19:34
    Other peoples comments may prove me wrong, but here's my 2cents worth.

    After looking at the program, Nothing jumps out at me as being incorrect.
    Do you have the circuit built or breadboarded?
    If the 555 timer circuits and
    Humidity Sensor HS1101 circuit and
    Temperature Sensor DS1620. are working correctly,
    To me, It looks like it would be worth trying.

    When I'm developing BS2 projects, I usually include a DEBUG statement in each subroutine that
    tells me which subroutine that I'm in something like DEBUG "in main", cr
    Most of the BS2 programs I've written tend to get stuck somewhere, and the DEBUG statements help me to find out
    mistakes in my logic.

    The DEBUG statements slow the program down, but those can be remarked out or removed
    when everything is working.
    I'll catch up to your age in about 3 years :)

    I hope this helps.
    I also hope others chime in.

    Gary
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-12-28 20:18
    I second Gary's suggestion of using debug statements. Whenever I have a program that doesn't work the way I expect it to I start cramming in the debug statements.

    Good luck with the humidity project. I tried having a controlled humidity environment once and it was a lot harder than I had thought it would be. The relative humidity changes drastically with temperature. I used an electric tea pot and an electric oven to attempt to control the temperature and humidity inside the oven. Often the humidity was too low or it was raining inside the oven. It was really tough trying to maintain a stable humidity.

    I like to think this sort of thing is possible (which of course it is) but just be aware it might be harder to achieve than you first planned.

    Oh, I almost forgot to make fun of you.

    Ha ha. You're old.

    Hey wait, I'm trying to get old too.

    Good for you! Good going. Way to get old! Keep up the good work!

    I'm trying to catch up to you guys.
  • 72sonett72sonett Posts: 82
    edited 2014-01-01 12:27
    I see little structure in the program... You use subroutines and GOSUBs (which is good) but there are no corresponding RETURNs.
    Normally when the CPU executes a GOSUB the return address is pushed on a stack and popped off with the RETURN at the end of the subroutine. Your program only pushes return addresses on the stack and never pops them off, a 'normal' processor would fill up all available stack space and then probably crash...

    Also, there is no END statement in your program, I would expect one at the end of the main program. If it were not for the conditions check, the Main: part of your program just 'falls into' the first subroutine.

    I would write your progam with one main never ending loop where I would measure temperature and humidity and based on the measured values call subroutines to switch on/off the fan and de/humidifier etc.

    The fun making part; you're only 4 years my senior...
  • IroneIrone Posts: 116
    edited 2014-01-01 18:16
    Hello,

    72sonett
    Before I posted this I thought that maybe I should have used GOTO's. I looked up GOTO's and GOSUB's and I believe a GOSUB is the same as a GOTO if you do not use a RETURN. I may be wrong. The Main: is really only a subroutine. I should change that to something like Start: or Begin: or something else. I meant to put a PAUSE 5000 before my last Main but forgot as I occasionally do. I tried using a DO....LOOP but got confused when it asked me for an ENDIF before the LOOP. The reason you see little structure is I am not very good at programming and have to ask for help from nice people like yourself who know much more than I do.

    Duane
    I believe the room where barley goes to sprouts will be held to between 48 degrees F and 58 degrees F so the relative humidity should not be a problem.

    One other problem that may affect me is in Central Pennsylvania in the winter the temperature goes below 0 degrees C and I have not factored that in my program. Could I just add 100 (50 C) to my temperature reading to keep it between -50C and +50C (122 F) and just use positive numbers just using a byte?
  • garyggaryg Posts: 420
    edited 2014-01-01 19:13
    From what I understand in PBASIC The GOSUB statement leaves a return address.
    I think that fact could cause you trouble if you keep calling the GOSUB without returning to it's original returning location.
    I believe that the GOTO statement is a blind directive that only sends the program to the GOTO
    without keeping a return address.
  • FranklinFranklin Posts: 4,747
    edited 2014-01-01 21:30
    I see a couple of changes you could make. On the GOTO/GOSUB issue, if you build code to be reused in several places you use GOSUB and a return. If you just want to go to a section of code and not come back GOTO is correct. In some of your IF statements, if you check for the bounds you don't need to check the inbetween.
     if a > 100 OR a < 10 THEN do item 1
    
    do item 2 << you don't need to test if a is between 10 and 100
    
    I hope this helps
  • 72sonett72sonett Posts: 82
    edited 2014-01-02 10:49
    This would be my version of your program;
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    'Humidity Sensor HS1101
    'Temperature Sensor DS1620
    'Checking Humidity and Comparing Temperature Inside and Outside to Control with
    'Either a Fan, Humidifier or a Humiditor
    
    '---------------Controls----------------------------------------------------
    
    Fan       PIN 5
    Hum       PIN 6
    DeHum     PIN 7
    
    '---------------Variables---------------------------------------------------
    
    OutTemp     VAR Byte
    InTemp      VAR Byte
    
    OutHum      VAR Word
    InHum       VAR Word
    
    '--------[ Initializations ]------------------------------------------------
    ' Note: DS1620 has been preprogrammed for mode 2.
    ' If not, uncomment the instructions on the next two lines on the first RUN
    ' HIGH 13: SHIFTOUT 15,14,[12,2]: LOW 13
    ' HIGH 10: SHIFTOUT 12,11,[12,2]: LOW 10
    Init:
      FREQOUT 0, 20, 3800                              ' Beep to signal that it is running.
      HIGH 13                                          ' Select the DS1620.
      SHIFTOUT 15, 14, LSBFIRST, [238]                 ' Send the "start conversions" command.
      LOW 13                                           ' Wait until called for.
    
      FREQOUT 0, 20, 3800                              ' Beep to signal that it is running.
      HIGH 10                                          ' Select the DS1620.
      SHIFTOUT 12, 11, LSBFIRST, [238]                 ' Send the "start conversions" command.
      LOW 13                                           ' Wait until called for.
    '-------------- Main Program------------------------------------------------------
    Main:
      DO                                               ' start loop
        HIGH 4                                         ' Start the 555 timer
        COUNT 3, 1000, InHum                           ' Read the inside Humidity
        LOW 4                                          ' Stop the 555 timer
    
        ' If  58% < inside humidity < 70% then try to adjust, otherwise just loop.
        IF (InHum <6468) OR (InHum >6626) THEN GOSUB OutsideHumidity
    
      LOOP                                             ' loop forever
    END                                                ' end main program.
    '===================== Subroutines =====================================================
    OutsideHumidity:
      HIGH 2                                           ' Start the 555 timer
      COUNT 1, 1000, OutHum                            ' Read the outside Humidity
      LOW 2                                            ' Stop the 555 timer
    
      IF (OutHum >=6468) AND (OutHum =<6626) THEN      ' If 58% < OutHum < 70%
        GOSUB Temperature                              ' check temperature and turn fan on/off
      ELSE                                             ' otherwise
        GOSUB INTERNAL_DEVICE                          ' try Internal Device
      ENDIF
    RETURN
    '-----------------------------------------------------------------------------
    Temperature:
    ' at this point;  6468 < OutHum =< 6626
      HIGH 13                                          ' Select the DS1620 InTemp.
      SHIFTOUT 15, 14, LSBFIRST, [170]                 ' Send the "get data" command.
      SHIFTIN 15, 14, LSBPRE, [InTemp]                 ' Get the data.
      LOW 13                                           ' End the command.
    
      HIGH 10                                          ' Select the DS1620 OutTemp.
      SHIFTOUT 12, 11, LSBFIRST, [170]                 ' Send the "get data" command.
      SHIFTIN 12, 11, LSBPRE, [OutTemp]                ' Get the data.
      LOW 10                                           ' End the command.
    
      IF OutTemp > (InTemp + 12) THEN                  ' If OutTemp is over InTemp by 6 degrees C
        LOW Fan                                        ' Turn off Fan
      ELSEIF OutTemp < (InTemp - 12) THEN              ' If OutTemp is under InTemp by 6 segrees C
          LOW Fan                                      ' Turn off Fan
        ELSEIF OutTemp < (InTemp + 12) THEN            ' If OutTemp is under InTemp by 6 dergees C
          HIGH Fan                                     ' Turn On Fan
          ELSEIF OutTemp > (InTemp - 12) THEN          ' If OutTemp is over InTemp by 6 degrees C
            HIGH Fan                                   ' Turn on Fan
          ENDIF
    RETURN
    '--------------------------------------------------------------------------
    Internal_Device:
    ' at this point; 6468 < OutHum =<6626
    ' InHum is determined in main loop
      IF InHum >6468 THEN                            ' If InHum is above 70%
        HIGH DeHum                                   ' Turn on Dehumidifier
      ELSEIF InHum <6574 THEN                        ' If InHum goes below 62%
        LOW DeHum                                    ' Turn off Dehumidifier
      ENDIF
    
      IF InHum > 6626 THEN                           ' If InHum is a below 58%
        HIGH Hum                                     ' Turn on Humidifier
      ELSEIF InHum <6535 THEN                        ' If InHum goes above 65%
        LOW Hum                                      ' Turn off Humidifier
      ENDIF
    
    RETURN
    '===================================================
    
    but there is still room for improvement e.g you could use a status nibble where you set indvidual bits in subroutines, and then once do an OUTB for the devices on I/O pins 4..7.

    If (InTemp < 12) then the evaluation of "IF OutTemp < (InTemp - 12) THEN..." may give unexpected results in unsigned 16-bit math.

    (I consider the use of GOTO to be harmful... )
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2014-01-02 12:21
    I believe the room where barley goes to sprouts will be held to between 48 degrees F and 58 degrees F so the relative humidity should not be a problem.

    One other problem that may affect me is in Central Pennsylvania in the winter the temperature goes below 0 degrees C and I have not factored that in my program. Could I just add 100 (50 C) to my temperature reading to keep it between -50C and +50C (122 F) and just use positive numbers just using a byte?

    You are right, the subzero values would not compare correctly. To simplify the logic, use Word variables to acquire the 9th bit from the DS1620 (the sign), and then either convert to Fahrenheit (so you can down to zero °F, -17.8°C) or as you suggest add a constant to make the values positive. The Fahrenheit value could fit into a byte, or even be offset down a bit more to cover those really cold winters!
    [SIZE=1][FONT=courier new][SIZE=1][FONT=courier new]  degC VAR Word
    [/FONT][/SIZE][/FONT][/SIZE][SIZE=1][FONT=courier new]  degK VAR Word
    [SIZE=1][FONT=courier new]  degF VAR Word
    [/FONT][/SIZE]  high 13                       ' select the DS1620
        shiftout 15,14,lsbfirst,[170] ' send the "get data" command
        shiftin 15,14,lsbpre,[degC\9]    ' get the data, including sign
      low 13                        ' end the command
      degC.byte1 = -degC.bit8       ' extend the sign to 16 bits
      degC = degC * 5               ' convert to 'C*10 (resolution 0.5 'C)
      degK = degC + 2732            ' convert to Kelvin*10 
      degF = degK * 9 / 50 - 459    ' convert to Fahrenheit, +/- 1 degree.
    [/FONT][/SIZE]
    

    +1 on suggestions from 72sonett, regarding program structure. Also +1 on Duane's comments about the issues of controlling both humidity and temperature. You scheme sounds workable though so long as the sprouts can tolerate some fluctuation.
  • CatspawCatspaw Posts: 49
    edited 2014-01-02 17:12
    GoTo's are like exit ramps. You're getting off the highway. You can get back on, but, you have to be deliberate about it. GoSub's are like a rest stop. You pull off and do your business (but you haven't really left the highway per se) then you go right back to going where you were going. The danger of goto's is if you were to use one in a subroutine you could end up in Hollyweird, CA. Back in the day before we had the concept of modules, we just put everything in subroutines. That compartmentalized everything into functions (Modules). It really cleans up the text of a program. We even initialized things with a sub. even though it was only used once because it got all that Smile out of the line of sight. Your program might end up looking like this:

    GOSUB INITIALIZE
    DO
    GOSUB Checkthis
    GOSUB TestResult
    GOSUB ActonResult
    LOOP
    Subroutines here

    Just my feeble attempt at participating. Trying to mentally jump start my return to this stuff. BTW, I've manually loaded binary boot addresses in equipment using toggle switches and got in line to enter my program with all the other guys carrying their punch cards rubber banded into modules in empty cardboard beer flats. Don't feel too old.
  • IroneIrone Posts: 116
    edited 2014-01-02 19:10
    Hello,

    I must tell you that besides the fact that I am old and not very good at programming I am lazy. I got some of my program from Web Applied Sensors (where the DS1650 came from) and the humidity sensor from the web, but I did read the datasheets. Would it be possible to set a T-high on the DS1650 at 45 C (113 F) to turn an output high? (At -1 C this reading would read out 127 C or 254 in 1/2 C). I could then check this pins state and then go to NEXT or to Internal_Device. We wouldn't ever need to fan in air less than freezing.
  • 72sonett72sonett Posts: 82
    edited 2014-01-03 05:16
    ... Would it be possible to set a T-high on the DS1620 at 45 C (113 F) to turn an output high?...
    Yes, from a DS1620 datasheet at e.g. http://pdf1.alldatasheet.com/datasheet-pdf/view/58506/DALLAS/DS1620.html I understand that is possible. Its pins 6&7 go high when the temperature is under or over preset limits, like a thermostat, so you could also directly switch a fan on/off... for that you do not need a basic stamp.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2014-01-03 10:01
    I posted Stamp code for DS1620 thermostat operation here. Note that it sends 9 bits twos complement to set the upper and lower trip points.
  • IroneIrone Posts: 116
    edited 2014-01-03 14:06
    Hello,

    Tracy, I used to know little about 2's compliment but with your explanation (Which I must study for 2 or 3 days.) may improve this old mind.

    Catspaw, My wife took a course in keypunching quite (More than quite!) a while ago.
Sign In or Register to comment.