Is timeout in effect a pause

johnlong

Senior Member
Hi All
In the serin command it says the following
#
The M2, X1 and X2 parts can take an optional timeout value and address at the
start of the command. The timeout value, set in milliseconds, is the length of
time the serin command will wait for a serial command to be detected. After the
timeout period , if no signal is detected, program flow will jump to the time out
address.
#
Is this in effect a pause and therefore not able to react to signals until it is released after the declared period
or is it a timer that can be interrupted at any time in the time frame chosen
I ask this because without the timeout and address the code funtions as expected
but when add it does not function
28x2 being used
serin A.1,T9600,fr works
serin [1000,fail],T9600,A.1,T9600,fr (the serout is being sent from a battery powered unit)
therefore without a release the main program will hang if the battery dies
regards
john
 

hippy

Technical Support
Staff member
Is this in effect a pause and therefore not able to react to signals until it is released after the declared period
An infinite pause is my understanding of it. If you don't have a timeout specified then everything jams up solid until data is received, interrupts on other pins won't be responded to until data is received.
 

johnlong

Senior Member
Hi Hippy
Once again I think I have not explained things clearly
serin A.1,T9600,fr ( this is working no hang up)
serin [1000,fail],T9600,A.1,T9600,fr (this is not working) (the serout is being sent from a battery powered unit , battery unit then waits for a responce)
So is any incoming data placed into the ram buffer within the timeout period. then after the timeout the buffer is checked and placed into the relivent variable specified. If no data in the ram location then address is envoked
regards
john
 

inglewoodpete

Senior Member
28x2 being used
If I was using a 28X2, it is likely that the background serial receive feature would be useful to allow interrupts to occur while waiting for serial data.

The problem with the SerIn in your code is that it only has a 1000mS 'window' to capture the incoming data. Depending on what other things are happening in your code, it could be easy to miss the incoming data.
 

hippy

Technical Support
Staff member
serin A.1,T9600,fr ( this is working no hang up)
serin [1000,fail],T9600,A.1,T9600,fr (this is not working)
I think you are going to have to explain exactly what you mean, detail what is happening and how you believe that diverges from what you expected to happen.

So is any incoming data placed into the ram buffer within the timeout period. then after the timeout the buffer is checked and placed into the relivent variable specified. If no data in the ram location then address is envoked
A SERIN without a timeout will wait for something to be received. When data is received the variable will be updated at that time, the SERIN command will immediately terminate and the next command will be executed. If no data is received the SERIN will simply keep waiting forever.

For a SERIN with a timeout it will also will wait for something to be received, and when data is received the variable will be updated at that time, the SERIN command will immediately terminate and the next command will be executed.

If no data has been received within the timeout period, the SERIN command will be exited, execution will continue from the timeout label if there is one.
 

hippy

Technical Support
Staff member
serin [1000,fail],T9600,A.1,T9600,fr
That is presumably a typo or transcription error because that won't pass syntax check, but I am wondering if you perhaps have the pin and baud rate reversed, have -

serin [1000,fail],T9600, A.1, fr

rather than -

serin [1000,fail], A.1, T9600, fr
 

johnlong

Senior Member
Hi Hippy
#post6 typo error serin [1000,fail],A.1,T9600, A.1, fr
Hi Inglewood pete
the reason I am using serial rather than hser for its background funtion is that I have a nextion display connected on the hser that I use
to alter the main units variables for time date temp ect and display the sensor results it is then used as an interrupt to alter variables at will and turn on or off pins to connect or disconnect mains supply to connected appliances .
The sensors are connected to a battery run remote sensor when I remove the timeouts things
work well up until a point were I think interferance distorts the link or battery failure occurs. That why I am working on a out of jail card to reset the units. To either reread or reset the slave and terminate the mains sub routine.
regards
john
 

lbenson

Senior Member
Can you post your whole code, or at least enough to show the error? Are you saying that the timeout (and jump to "fail:") doesn't occur? When you are not in SERIN, do you have any pauses? For instance, if you have a PAUSE 1000 anywhere, then you have only about a 50% chance that your SERIN will catch a transmission. Any other blocking code will also be a problem.
 

johnlong

Senior Member
Hi All
I have extended the wait periods in the ser command lines
Noticed when I placed debugs in the slave code at each write the master responded as expected
when removed only captures the battery read before escapping
MASTER CODE
Code:
'Connection for the DRF1276DM to the picaxe 28X2
'picaxe A.1(TXD)--------Pin 4 (RXD) DRF
'picaxe A.2(RXD)--------Pin 5 (TXD) DRF
'used to wake up Picaxe up from sleep mode

#picaxe 28x2
#no_data
#no_table

 Symbol Qualifier= 254 
 symbol QT=34
 symbol area=80
symbol fail=b25
symbol lamp=w7
symbol dry=w8
symbol rh=w9
symbol linked=b8
symbol fr=b10
symbol hum=b9
symbol batt=w3    
     hsersetup   B9600_8, %00
    pause 2000
      MAIN:
      do 
        
    w10=w10+1      
     hserout 0, ("t1.txt=",QT,#w10,QT,$ff,$ff,$ff)
  
   serout A.1,T9600,(85,85,85,85,Qualifier,"Hello")'wake up slave call
      serin A.2,T9600,(Qualifier,"ACK")' slave connected responce
      serin A.2,T9600,linked
      hserout 0, ("t3.txt=",QT,#linked,QT,$ff,$ff,$ff)
     
     if linked=0 then ' indicates running slot 1 on slave to initalise HTU21D on first up power
        goto lingalong
        elseif linked=1 then
            goto obtain
    endif 
obtain:    
        serin A.2,T9600,(qualifier,"report")'1st recieve
    volt:
            serin[3000,lingalong],A.2,T9600,b6,b7'2r battery voltage 
                serout A.1,T9600,(b6,b7)'3s
                serin[3000,lingalong],A.2,T9600,b2
                if b2=1 then
                goto volt
                elseif b2=0 then
                    pause 50
                hserout 0, ("bt.txt=",QT,#batt,QT,$ff,$ff,$ff)
                hserout 0, ("sn1.txt=",QT,#b2,QT,$ff,$ff,$ff)
                endif
    htut:            '*********************** writes up to this point
             serin[3000,lingalong], A.2,T9600,dry 'result from remote unit temprature read
             serout A.1,T9600,(dry) 'bounce result back to check for errors
             serin[3000,lingalong],A.2,T9600,b2 'master waits until conformation of value or error from slave
             if b2=1 then
                goto htut
                elseif b2=0 then
                    pause 50
              hserout 0, ("tm1.txt=",QT,#dry,QT,$ff,$ff,$ff)
            hserout 0, ("sn1.txt=",QT,#b2,QT,$ff,$ff,$ff)
            endif
    huth:
            serin[3000,lingalong],A.2,T9600,rh 'result from remote unit humidity read
             serout A.1,T9600,(rh) 'bounce result back to check for errors
              serin[3000,lingalong],A.2,T9600,b2 'master waits until conformation of value or error from slave
             if b2=1 then
                goto huth
                elseif b2=0 then
                    pause 50
                hserout 0, ("hm.txt=",QT,#rh,QT,$ff,$ff,$ff)
             hserout 0, ("sn1.txt=",QT,b2,QT,$ff,$ff,$ff)
            endif
    shine:        
             serin[3000,lingalong],A.2,T9600,lamp 'result from remote unit photoresisstor
             serout A.1,T9600,(lamp) 'bounce result back to check for errors
             serin[3000,lingalong],A.2,T9600,b2 'master waits until conformation of value or error from slave
            
              if b2=1 then
                goto shine
                elseif b2=0 then
                    pause 50
            hserout 0, ("lp.txt=",QT,#lamp,QT,$ff,$ff,$ff)
         hserout 0, ("sn1.txt=",QT,#b2,QT,$ff,$ff,$ff)
         endif
            
    alarm:        
             serin[3000,lingalong],A.2,T9600,fr 'result from remote unit ds18b20
             serout A.1,T9600,(fr) 'bounce result back to check for errors
             serin[3000,lingalong],A.2,T9600,b2 'master waits until conformation of value or error from slave
            if b2=1 then
                goto alarm
                elseif b2=0 then
                    pause 50
                 hserout 0, ("tm2.txt=",QT,#fr,QT,$ff,$ff,$ff)
                hserout 0, ("sn1.txt=",QT,#b2,QT,$ff,$ff,$ff)
            endif
    lingalong:
     b5="z"
    serout A.1,T9600,(b5)
    high B.7
    for b10= 1 to 30
         hserout 0, ("t3.txt=",QT,#b10,QT,$ff,$ff,$ff)
     pause 2000
    next b10
    low B.7
    loop

    return
regards john
 

johnlong

Senior Member
SLAVE CODE
Code:
  ;Adaptied from Phillip J Hornby HTU21D_demo.bas 22/02/17 code comments by P Hornsby unless **
  'Connection for the DRF1276DM to the picaxe 28X2
'picaxe B.0(TXD)--------Pin 4 (RXD) DRF
'picaxe B.1(RXD)--------Pin 5 (TXD) DRF
'picaxe B.2--------Pin 6 (AUX) DRF indication of data in/out 2ms in advance of send/recieve
'used to wake up Picaxe up from sleep mode        UNIT SETTINGS FOR drf1276dm
                '28x2                 power level 6 RF-freq 433.9 RF_bw 125 RF_Factor 2048 baud 9600
    '            ---------------
      'photo resistor    | A.0        B.2  | AUX  to Pin 6 (AUX) DRF
    '            |            B.1  | RXD  to Pin 5 (TXD) DRF
    '            |            B.0  | TXD  to Pin 4 (RXD) DRF
    ''            |            C.4  | SDA to HTU21D-F Adafruit breakout board 3v to 5v using 5v
    '    DS18B20    |C.2         C.3  | SCL to HTU21-F

     
     '#rem
#no_data
#no_table
#slot 0

symbol TD7 = b7 symbol TD6=b6 symbol TD5=b5 symbol TD4=b4 symbol TD3=b3 symbol TD2=b2 symbol TD1=b1 symbol TD0=b0
symbol error=b45
symbol themode=b20
'**************************
symbol result=w23 'b46,b47
symbol RH=b50
 Symbol Qualifier= 254 'used for wireless communications
 symbol batt=w15
symbol fail=b25
symbol want=b26
symbol lamp=w18
symbol DSB=w21
symbol Dry     = W24 ;b48,b49
symbol rxCRC         = b51
symbol HTU21Data         = W26 'b53,b52
 symbol LSB         =  b52
 symbol MSB         =  b53
symbol CRC             = b54
symbol DATABYTE         = b55
symbol HTU21DAddress = %10000000:symbol TemperatureHOLD=$E3:symbol HumidityHOLD = $E5:symbol TemperatureNOHOLD = $F3
symbol HumidityNOHOLD = $F5:symbol WriteUser = $E6:symbol ReadUser = $E7:symbol SoftReset = $FE                
symbol Heater = 2:symbol SupplyOK = 6:symbol POLY = 0x31;Used in CRC generation => X^8 + X^5 + X^4 + 1
; I2C registers                
symbol sspmsk = $6F:symbol sspcon2 = $C5:symbol sspcon1 = $C6:symbol sspstat = $C7:symbol sspadd = $C8
symbol sspbuf = $C9
; SSPCON2 bits
symbol SEN = 0:symbol PEN = 2:symbol ACKSTAT = 6
symbol HTU21D_0= 17474:symbol HTU21D_Minus40= 2555:symbol HTU21D_4685= 34948:symbol HTU21D_80= 47310:symbol HTU21D_125= 64092
;Closest value to 0 (0.0026);Closest value to -40 (-39.999);Closest value to 46.85 (46.855);closest value to 80 (80.001)
;Closest value to 125 (124.998)
    
    #macro ComputeCRC(val1,val2)
        CRC = 0                        ;crc_t crc_init - in original 'C' code
        DATABYTE = val1 : gosub crc_update        ;msb
        DATABYTE = val2 : gosub crc_update        ;lsb
    #endm    

    #macro ComputeCRC1(val)
        CRC = 0                        ;crc_t crc_init - in original 'C' code
        DATABYTE = val : gosub crc_update        ;msb
    #endm
    
    
    hi2csetup i2cmaster,HTU21DAddress,i2cfast,i2cbyte
    hintsetup %00000100
    adcsetup=1
    pause 1000
'*******************************************************************************
main: 
    do 
        low b.7
    read 80,@bptr
    if @bptr=1 then
        run 1
    endif 
       enablebod 'low power
     sleep 0 'woken up via pin B.2 attached to AUX on DRF sets hint and hint2 flags
     disablebod 'power up
    Serin B.1, T9600,(Qualifier,"Hello") 'call from master DRF unit
    
    hintflag=0:hint2flag=0
    pause 500
    serout B.0,T9600,(Qualifier,"ACK")
    pause 500
    if themode=0 then
        serout B.0,T9600,(themode)
        run 1    
        elseif themode=1 then
    serout B.0,T9600,(themode)
    endif
    fail=0
    high b.7
battcal:    'code for voltage writen by Marks
    w14 = 0                                        '  1023 x 1.024v /209   = (5.012v) 
       FOR b0 = 1 TO 25                                    '  1023 x 1.024v /209.5 = (5.000v)
      CALIBADC10 w15  : w14 = w14 +w15 '              1023 x 1.024v /210   = (4.988v)      
       NEXT b0                                             '  1023 x 1.024v /511   = (2.050v)
                                                            '  1023 x 1.024v /512   = (2.046v)       
    w16 = w14 +24/25  
    w14 = w14 /25   
       w15 = 65472 // w14 *8 /w14       ' 1023 steps x 1024 mV = 1047552 / 16 = 65472
      w15 = 65472 /  w14 *8 +w15
      w15 = 65472 // w16 *8 /w16 +w15        ' double resolution by attemping to detect intermediate steps.
      w15 = 65472 /  w16 *8 +w15 
      if fail=1 then
        goto rone
    endif 
    
tempread:
    hi2cin TemperatureHOLD,(MSB,LSB,rxCRC)        ;temperature measurement next case
                                    ;rely on CRC to detect any comms error
    ComputeCRC(MSB,LSB)'gosub crc update
    
    result = HTU21Data & $FFFC            ;zero bottom 2 bits
    if result < HTU21D_0 then            ;-ve?
    W1 = HTU21D_4685 - result min HTU21D_Minus40    ;and constrain min to -40.0
    else                                ;otherwise positive...
        W1 = result max HTU21D_125        ;...constrain max to +125.0
    endif
    dry = 17572 ** W1 - 4685            ;Basic calculation
    dry = dry + 5 / 10
    
    bintoascii Dry,TD0,TD1,TD2,TD3,TD4    ;Temperature = 10 x Temp (i.e. 1dp)    
    dry= TD2-48*10 '** round up to whole values
    TD3=TD3-48
    TD4=TD4-48    
    if TD4>=5 then
    TD3=TD3+1
    endif     
    dry=dry+TD3
    if fail=1 then
        goto rtwo
        endif
    '************************************************************

humread:
    hi2cin HumidityHOLD,(MSB,LSB,rxCRC)            ;humidity measurement
    ComputeCRC(MSB,LSB)
    
    W0 = HTU21Data & $FFFC                    ;zero bottom 2 bits
    RH = 125 ** W0 MIN 6 - 6 max 100        ;Constrain RH to 0~100%
    if result >= HTU21D_0 and result =< HTU21D_80 then ; only applies between 0 and 80.0

    W0 = 250 - dry                    ;part 1 of calculation (25-Tempactual)
    if W0 >= $8000 then                    ;sign bit set.
    W0 = - W0 * 15                    ;Negative - make it positive (neg * n
    if W0 >= 1000 then
    W1 = W0 / 1000                ;Get no. of whole %age points
    RH = RH + W1 max 100    ;and apply (constrain to 100%)
    W1 = W1 * 1000                ;get...
    W0 = W0 - W1                ;...remainder    
    endif
    if W0 >= 500 then                    ;500 = 0.5 percent
    RH = RH + 1 max 100    ;correct and constrain to 100%
    endif
    else
        
    W0 = W0 * 15
        
    if W0 >= 1000 then
    W1 = W0 / 1000
    if RH > W1 then            ;Don't end up up with RH < 0%
    RH = RH - W1    ;Correct it...
    else
    RH = 0            ;...or set to min.
    endif
    W1 = W1 * 1000
    W0 = W0 - W1
    endif
            
    if W0 >= 500 then                    ;500 = 0.5 percent
    if RH >= 1 then            ;Don't end up up with RH < 0%
    RH = RH - 1        ;otherwise, correct it.
    endif
    endif
    endif
    endif
    if fail=1 then
        goto rthr
        endif
day:
    readadc A.0,lamp 
    if fail=1 then
        goto rfor
        endif
fire:
     readtemp C.2,DSB 
    if fail=1 then
        goto rfiv
        endif
    
    
'*************
    serout B.0,T9600,(qualifier,"report")'1st send
    pause 20
rone: 
    serout B.0,T9600,(b30,b31)'2s
     serin[3000,main],B.1,T9600,b12,b13'3r
     
     if w6<>batt and fail=0 then
         fail=1
         serout B.0,T9600,(fail)
         goto battcal
    else
         fail=0
          serout B.0,T9600,(fail)
         w6=0
        endif
    
rtwo:    
     serout B.0,T9600,(dry)
     serin[3000,main],B.1,T9600,w6
     if w6<>dry and fail=0 then
         fail=1
         serout B.0,T9600,(fail)
         goto tempread
    else
         fail=0
          serout B.0,T9600,(fail)
         w6=0
        endif

rthr:        
     serout B.0,T9600,(rh)
      serin[3000,main],B.1,T9600,w6
      if w6<>rh and fail=0 then
         fail=1
         serout B.0,T9600,(fail)
         goto humread
    else
         fail=0
          serout B.0,T9600,(fail)
         w6=0
        endif
rfor: 
     serout B.0,T9600,(lamp)
      serin[3000,main],B.1,T9600,w6
    if w6<>lamp and fail=0 then
         fail=1
         serout B.0,T9600,(fail)
         goto day
    else
         fail=0
          serout B.0,T9600,(fail)
         w6=0
        endif
rfiv: 
     serout B.0,T9600,(dsb)
     serin[3000,main],B.1,T9600,w6
     if w6<>dsb and fail=0 then
         fail=1
         serout B.0,T9600,(fail)
         goto fire
    else
         fail=0
          serout B.0,T9600,(fail)
         w6=0
        endif
    do
     serin B.1,T9600,want
loop until want="z"
    want=0
    hintflag=0:hint2flag=0
    
loop
      '******************************subs
    
    
    
    crc_update:
    pushram                            ;20x2 extravagance!
    b1 = %10000000            ;make a mask, to examine the incoming byte, bit by bit...
    for b2 = 7 to 0 step -1                    ;...working from Right to left.
    bit0 = CRC AND %10000000 / %10000000     ;get the current state of bit7 of the CRC 
    b3 = DATABYTE AND b1        ;is the bit being examined via our mask, SET in the data byte
        if b3 <> 0 then                    ;YES
            bit0 = NOT bit0                ;complement the bit obtained from CRC bit7
        endif
        CRC = CRC * 2                    ;shift CRC one place left
        if bit0 = 1 then
    CRC = CRC XOR POLY    ; probably deeply significant ;-) (XOR = Division without carry)
        endif
        b1 = b1 / 2                    ;Shift mask right to point at next bit of data
    next b2
    popram
    return
    '#endrem
'***********************************************************8
 

hippy

Technical Support
Staff member
If things work with DEBUG in place but not without that suggests there are timing issues.

Asynchronous networking can be incredibly complicated, and especially so when dumb RF modules are in use, as seems to be the case here.

That's compounded because, in the master, there is RF going on and background comms, there are some SERIN with timout and some without, and, in the slave, RF, I2C, READTEMP, multiple-slots, interrupts, and a whole lot of flag status being passed around.

If just one thing goes wrong or gets out of kilter then the whole house of cards can collapse in on itself and this seems to be a case of that.

Unfortunately it is sometimes the case that things can get so complicated that it's impossible to tell what is going on at any point in time, and there may be little option but to strip everything back to the bare basics, or start again, and build up from there.
 

Aries

New Member
From my own experience ...
If you have serin/serout/sertxd etc active at the same time as I2C, then you can find that the I2C hangs (due to timing issues). If you have control of the serial processing and I2C, then you are probably all right. But, if you have hserin with background receive, or are a slave, then you cannot control when both I2C and serial i/o happen together.
 

johnlong

Senior Member
Hi All
reconfigured the codes to turn on and off i2c and hser and at the time of writting had 389 reads without a blimp
Aries thanks for the comments you spurred the old memory, remembered I had to turn on and off the
hser commands to read the ds1307 rtc correctly in the main code
Hippy is there a list of all the used flags in the picaxe system I know of the hint ,hser and timer are there others

Code:
'Connection for the DRF1276DM to the picaxe 28X2
'picaxe A.1(TXD)--------Pin 4 (RXD) DRF
'picaxe A.2(RXD)--------Pin 5 (TXD) DRF
'used to wake up Picaxe up from sleep mode

#picaxe 28x2
#no_data
#no_table

 Symbol Qualifier= 254 
 symbol QT=34
 symbol area=80
symbol fail=b25
symbol lamp=w7
symbol dry=w8
symbol rh=w9
symbol linked=b8
symbol fr=b10
symbol hum=b9
symbol batt=w3    
     'hsersetup   B9600_8, %01
    pause 2000
      MAIN:
      do
      gosub obtain
      if linked=1 then
      gosub update
      endif
      high B.7
    for b10= 1 to 30
     hserout 0, ("t3.txt=",QT,#b10,QT,$ff,$ff,$ff)
     pause 2000
    next b10
    low B.7
    w10=w10+1      
     hserout 0, ("t1.txt=",QT,#w10,QT,$ff,$ff,$ff)
    loop

obtain:    
        hsersetup off
         serout A.1,T9600,(85,85,85,85,Qualifier,"Hello")'wake up slave call
          serin[3000,lingalong], A.2,T9600,(Qualifier,"ACK")' slave connected responce
          serin[3000,lingalong], A.2,T9600,linked
     
         if linked=0 then ' indicates running slot 1 on slave to initalise HTU21D on first up power
        goto lingalong
        else 
        serin[3000,lingalong], A.2,T9600,(qualifier,"report")'1st recieve
        endif
    volt:
            serin[3000,lingalong],A.2,T9600,b6,b7'2r battery voltage 
                serout A.1,T9600,(b6,b7)'3s
                serin[3000,lingalong],A.2,T9600,b2
                if b2=1 then
                goto volt
                endif
    htut:            '*********************** writes up to this point
             serin[3000,lingalong], A.2,T9600,dry 'result from remote unit temprature read
             serout A.1,T9600,(dry) 'bounce result back to check for errors
             serin[3000,lingalong],A.2,T9600,b3 'master waits until conformation of value or error from slave
             if b3=1 then
                goto htut
            endif
    huth:
            serin[3000,lingalong],A.2,T9600,rh 'result from remote unit humidity read
             serout A.1,T9600,(rh) 'bounce result back to check for errors
              serin[3000,lingalong],A.2,T9600,b4 'master waits until conformation of value or error from slave
             if b4=1 then
                goto huth
            endif
    shine:        
             serin[3000,lingalong],A.2,T9600,lamp 'result from remote unit photoresisstor
             serout A.1,T9600,(lamp) 'bounce result back to check for errors
             serin[3000,lingalong],A.2,T9600,b5 'master waits until conformation of value or error from slave
            
              if b5=1 then
                goto shine
            endif
            
    alarm:        
             serin[3000,lingalong],A.2,T9600,fr 'result from remote unit ds18b20
             serout A.1,T9600,(fr) 'bounce result back to check for errors
             serin[3000,lingalong],A.2,T9600,b6 'master waits until conformation of value or error from slave
            if b6=1 then
                goto alarm        
            endif 
        lingalong:
        hsersetup   B9600_8, %01
        return
    update:
        
        hserout 0, ("bt.txt=",QT,#batt,QT,$ff,$ff,$ff)
        hserout 0, ("sn1.txt=",QT,#b2,QT,$ff,$ff,$ff)
        
        hserout 0, ("tm1.txt=",QT,#dry,QT,$ff,$ff,$ff)
        hserout 0, ("sn2.txt=",QT,#b3,QT,$ff,$ff,$ff)
        
        hserout 0, ("hm.txt=",QT,#rh,QT,$ff,$ff,$ff)
        hserout 0, ("sn1.txt=",QT,#b4,QT,$ff,$ff,$ff)
        
        hserout 0, ("lp.txt=",QT,#lamp,QT,$ff,$ff,$ff)
        hserout 0, ("sn2.txt=",QT,#b5,QT,$ff,$ff,$ff)
        
        hserout 0, ("tm2.txt=",QT,#fr,QT,$ff,$ff,$ff)
        hserout 0, ("sn1.txt=",QT,#b6,QT,$ff,$ff,$ff)
        return
 

johnlong

Senior Member
The remote sensor code
Code:
  ;Adaptied from Phillip J Hornby HTU21D_demo.bas 22/02/17 code comments by P Hornsby unless **
  'Connection for the DRF1276DM to the picaxe 28X2
'picaxe B.0(TXD)--------Pin 4 (RXD) DRF
'picaxe B.1(RXD)--------Pin 5 (TXD) DRF
'picaxe B.2--------Pin 6 (AUX) DRF indication of data in/out 2ms in advance of send/recieve
'used to wake up Picaxe up from sleep mode        UNIT SETTINGS FOR drf1276dm
                '28x2                 power level 6 RF-freq 433.9 RF_bw 125 RF_Factor 2048 baud 9600
    '            ---------------
      'photo resistor    | A.0        B.2  | AUX  to Pin 6 (AUX) DRF
    '            |            B.1  | RXD  to Pin 5 (TXD) DRF
    '            |            B.0  | TXD  to Pin 4 (RXD) DRF
    ''            |            C.4  | SDA to HTU21D-F Adafruit breakout board 3v to 5v using 5v
    '    DS18B20    |C.2         C.3  | SCL to HTU21-F

     
    ' #rem
#no_data
#no_table
#slot 0

symbol TD7 = b7 symbol TD6=b6 symbol TD5=b5 symbol TD4=b4 symbol TD3=b3 symbol TD2=b2 symbol TD1=b1 symbol TD0=b0
symbol error=b45
symbol themode=b20
'**************************
symbol result=w23 'b46,b47
symbol RH=b50
 Symbol Qualifier= 254 'used for wireless communications
 symbol batt=w15
symbol fail=b25
symbol want=b26
symbol lamp=w18
symbol DSB=w21
symbol Dry     = W24 ;b48,b49
symbol rxCRC         = b51
symbol HTU21Data         = W26 'b53,b52
 symbol LSB         =  b52
 symbol MSB         =  b53
symbol CRC             = b54
symbol DATABYTE         = b55
symbol HTU21DAddress = %10000000:symbol TemperatureHOLD=$E3:symbol HumidityHOLD = $E5:symbol TemperatureNOHOLD = $F3
symbol HumidityNOHOLD = $F5:symbol WriteUser = $E6:symbol ReadUser = $E7:symbol SoftReset = $FE                
symbol Heater = 2:symbol SupplyOK = 6:symbol POLY = 0x31;Used in CRC generation => X^8 + X^5 + X^4 + 1
; I2C registers                
symbol sspmsk = $6F:symbol sspcon2 = $C5:symbol sspcon1 = $C6:symbol sspstat = $C7:symbol sspadd = $C8
symbol sspbuf = $C9
; SSPCON2 bits
symbol SEN = 0:symbol PEN = 2:symbol ACKSTAT = 6
symbol HTU21D_0= 17474:symbol HTU21D_Minus40= 2555:symbol HTU21D_4685= 34948:symbol HTU21D_80= 47310:symbol HTU21D_125= 64092
;Closest value to 0 (0.0026);Closest value to -40 (-39.999);Closest value to 46.85 (46.855);closest value to 80 (80.001)
;Closest value to 125 (124.998)
    
    #macro ComputeCRC(val1,val2)
        CRC = 0                        ;crc_t crc_init - in original 'C' code
        DATABYTE = val1 : gosub crc_update        ;msb
        DATABYTE = val2 : gosub crc_update        ;lsb
    #endm    

    #macro ComputeCRC1(val)
        CRC = 0                        ;crc_t crc_init - in original 'C' code
        DATABYTE = val : gosub crc_update        ;msb
    #endm
    
    
    
    hintsetup %00000100
    adcsetup=1
    pause 1000
'*******************************************************************************
main: 
    do 
        low b.7
    read 80,@bptr
    if @bptr=1 then
        run 1
    endif 
       enablebod 'low power
     sleep 0 'woken up via pin B.2 attached to AUX on DRF sets hint and hint2 flags
     disablebod 'power up
    Serin B.1, T9600,(Qualifier,"Hello") 'call from master DRF unit
    
    hintflag=0:hint2flag=0
    pause 100
    serout B.0,T9600,(Qualifier,"ACK")
    pause 100
    if themode=0 then
        serout B.0,T9600,(themode)
        run 1    
        elseif themode=1 then
    serout B.0,T9600,(themode)
    endif
    fail=0
    high b.7
battcal:    'code for voltage writen by Marks
    w14 = 0                                        '  1023 x 1.024v /209   = (5.012v) 
       FOR b0 = 1 TO 25                                    '  1023 x 1.024v /209.5 = (5.000v)
      CALIBADC10 w15  : w14 = w14 +w15 '              1023 x 1.024v /210   = (4.988v)      
       NEXT b0                                             '  1023 x 1.024v /511   = (2.050v)
                                                            '  1023 x 1.024v /512   = (2.046v)       
    w16 = w14 +24/25  
    w14 = w14 /25   
       w15 = 65472 // w14 *8 /w14       ' 1023 steps x 1024 mV = 1047552 / 16 = 65472
      w15 = 65472 /  w14 *8 +w15
      w15 = 65472 // w16 *8 /w16 +w15        ' double resolution by attemping to detect intermediate steps.
      w15 = 65472 /  w16 *8 +w15 
      if fail=1 then
        goto rone
    endif 
    
tempread:
    hi2csetup i2cmaster,HTU21DAddress,i2cfast,i2cbyte
    pause 20
    hi2cin TemperatureHOLD,(MSB,LSB,rxCRC)        ;temperature measurement next case
                                    ;rely on CRC to detect any comms error
    ComputeCRC(MSB,LSB)'gosub crc update
    
    result = HTU21Data & $FFFC            ;zero bottom 2 bits
    if result < HTU21D_0 then            ;-ve?
    W1 = HTU21D_4685 - result min HTU21D_Minus40    ;and constrain min to -40.0
    else                                ;otherwise positive...
        W1 = result max HTU21D_125        ;...constrain max to +125.0
    endif
    dry = 17572 ** W1 - 4685            ;Basic calculation
    dry = dry + 5 / 10
    
    bintoascii Dry,TD0,TD1,TD2,TD3,TD4    ;Temperature = 10 x Temp (i.e. 1dp)    
    dry= TD2-48*10 '** round up to whole values
    TD3=TD3-48
    TD4=TD4-48    
    if TD4>=5 then
    TD3=TD3+1
    endif     
    dry=dry+TD3
    hi2csetup off
    if fail=1 then
        goto rtwo
        endif
    '************************************************************

humread:
    hi2csetup i2cmaster,HTU21DAddress,i2cfast,i2cbyte
    pause 20
    hi2cin HumidityHOLD,(MSB,LSB,rxCRC)            ;humidity measurement
    ComputeCRC(MSB,LSB)
    
    W0 = HTU21Data & $FFFC                    ;zero bottom 2 bits
    RH = 125 ** W0 MIN 6 - 6 max 100        ;Constrain RH to 0~100%
    if result >= HTU21D_0 and result =< HTU21D_80 then ; only applies between 0 and 80.0

    W0 = 250 - dry                    ;part 1 of calculation (25-Tempactual)
    if W0 >= $8000 then                    ;sign bit set.
    W0 = - W0 * 15                    ;Negative - make it positive (neg * n
    if W0 >= 1000 then
    W1 = W0 / 1000                ;Get no. of whole %age points
    RH = RH + W1 max 100    ;and apply (constrain to 100%)
    W1 = W1 * 1000                ;get...
    W0 = W0 - W1                ;...remainder    
    endif
    if W0 >= 500 then                    ;500 = 0.5 percent
    RH = RH + 1 max 100    ;correct and constrain to 100%
    endif
    else
        
    W0 = W0 * 15
        
    if W0 >= 1000 then
    W1 = W0 / 1000
    if RH > W1 then            ;Don't end up up with RH < 0%
    RH = RH - W1    ;Correct it...
    else
    RH = 0            ;...or set to min.
    endif
    W1 = W1 * 1000
    W0 = W0 - W1
    endif
            
    if W0 >= 500 then                    ;500 = 0.5 percent
    if RH >= 1 then            ;Don't end up up with RH < 0%
    RH = RH - 1        ;otherwise, correct it.
    endif
    endif
    endif
    endif
    
    if fail=1 then
        goto rthr
    endif 
    hi2csetup off
day:
    readadc A.0,lamp
    
    if fail=1 then
        goto rfor
        endif
fire:
     readtemp C.2,DSB
     
    if fail=1 then
        goto rfiv
        endif
    
    
'*************
    serout B.0,T9600,(qualifier,"report")'1st send
    pause 20
rone: 
    serout B.0,T9600,(b30,b31)'2s
     serin[3000,main],B.1,T9600,b12,b13'3r
     
     if w6<>batt and fail=0 then
         fail=1
         serout B.0,T9600,(fail)
         goto battcal
    else
         fail=0
          serout B.0,T9600,(fail)
         w6=0
        endif
    
rtwo:        pause 50
     serout B.0,T9600,(dry)
     serin[3000,main],B.1,T9600,w6
     if w6<>dry and fail=0 then
         fail=1
         serout B.0,T9600,(fail)
         goto tempread
    else
         fail=0
          serout B.0,T9600,(fail)
         w6=0
        endif

rthr:      pause 50    
     serout B.0,T9600,(rh)
      serin[3000,main],B.1,T9600,w6
      if w6<>rh and fail=0 then
         fail=1
         serout B.0,T9600,(fail)
         goto humread
    else
         fail=0
          serout B.0,T9600,(fail)
         w6=0
        endif
rfor:   pause 50
     serout B.0,T9600,(lamp)
      serin[3000,main],B.1,T9600,w6
    if w6<>lamp and fail=0 then
         fail=1
         serout B.0,T9600,(fail)
         goto day
    else
         fail=0
          serout B.0,T9600,(fail)
         w6=0
        endif
rfiv:  pause 50
     serout B.0,T9600,(dsb)
     serin[3000,main],B.1,T9600,w6
     if w6<>dsb and fail=0 then
         fail=1
         serout B.0,T9600,(fail)
         goto fire
    else
         fail=0
          serout B.0,T9600,(fail)
         w6=0
    endif 
    flags=0
    hintflag=0:hint2flag=0
    
loop
      '******************************subs
    
    
    
    crc_update:
    pushram                            ;20x2 extravagance!
    b1 = %10000000            ;make a mask, to examine the incoming byte, bit by bit...
    for b2 = 7 to 0 step -1                    ;...working from Right to left.
    bit0 = CRC AND %10000000 / %10000000     ;get the current state of bit7 of the CRC 
    b3 = DATABYTE AND b1        ;is the bit being examined via our mask, SET in the data byte
        if b3 <> 0 then                    ;YES
            bit0 = NOT bit0                ;complement the bit obtained from CRC bit7
        endif
        CRC = CRC * 2                    ;shift CRC one place left
        if bit0 = 1 then
    CRC = CRC XOR POLY    ; probably deeply significant ;-) (XOR = Division without carry)
        endif
        b1 = b1 / 2                    ;Shift mask right to point at next bit of data
    next b2
    popram
    return
    #endrem
 

hippy

Technical Support
Staff member
Hippy is there a list of all the used flags in the picaxe system I know of the hint ,hser and timer are there others
PICAXE Manual 2, "Variables - Special function", page 24 for the 20X2 and 28X2 ...

Code:
flag0 hint0flag hardware interrupt on pin INT0
flag1 hint1flag hardware interrupt on pin INT1
flag2 hint2flag hardware interrupt on pin INT2
flag3 hintflag  hardware interrupt on any pin 0,1,2
flag4 compflag  hardware interrupt on comparator
flag5 hserflag  hserial background receive has occurred
flag6 hi2cflag  hi2c write has occurred (slave mode)
flag7 toflag    timer overflow flag
 
Top