Shop OBEX P1 Docs P2 Docs Learn Events
QuickStart board + RPi = ? — Parallax Forums

QuickStart board + RPi = ?

RsadeikaRsadeika Posts: 3,837
edited 2015-06-23 05:10 in Propeller 1
I gave up on the Propeller IDE, and I am now using the Propeller Tool, since I work on a Windows box. I am doing more tests with the mentioned prototype setup which consists of a QuickStart board, Raspberry Pi 2, and an XBee module. I will be adding a sht11 module, and possibly multiple DS18B20 doodads, and other doodads if I have enough COGs left. And of course the QS is a stand in for a Propeller HAT.

The intention is to have the Propeller drive the modules and sensors, while the RPi can do the data logging and other heavy lifting, like providing date and time, as an example. On the Propeller side, so far the RAM usage is minimal, but should increase, quite a bit, when I add the sht11 object to the mix.

So, the way this works, you need an XBee module connected to your PC, with a terminal program that logs into the XBee, then you will have a UI session with the Propeller program. Of course on the RPi side, I am using a freeBasic terminal program, which will be able to be run from an ssh login or an xrdp login. The command structure will be similar to what you get on the XBee side. The final goal, be able to get things like temperature readings from the placed sensors, set up specific data logging requirements, data log(s) will be saved on the RPI, ..., etc. Hope all this works as imagined, but then you never know what will happen, probably run out of COGS, or is memory come first?

As an aside, I noticed that PIMORONI sells some kind of mobile pi power thing. Now if you can mount that, and then mount a Propeller HAT on top of that, Hmm, could be an interesting setup.

Ray
' Xsensor2.spin
' June 10, 2015
' Using the Propeller Tool
' UI on XBee and RPi

CON
  _clkmode   = xtal1 + pll16x                           
  _xinfreq   = 5_000_000

OBJ
  term : "Extended_FDSerial"
  rpi  : "Extended_FDSerial"
  misc : "tools"

VAR
  long oneStack[100]
  
PUB Start
'            Rx Tx         On QS board
  term.start(26,24,0,9600)  ' Connect to XBee module
  rpi.start(27,25,0,115200) ' Connect to RPi /dev/ttyAMA0

  cognew(talkRPI, @oneStack) ' COG for RPi connection

  main

PUB main | inSbyte,inAbyte,workbyte

  term.str(string("Press CR to continue",10,13))
  repeat
    inSbyte := term.Rx  ' Waiting for a CR.
    if inSbyte == 13
      term.str(string("Welcome",10,13))
      repeat
        term.Tx("#")
        term.RxStr(@inStrg)
        if strcomp(@inStrg, @stopProg)  ' If Quit
          term.str(@inStrg)
          CRLF
          term.str(string("Program Stopped!",10,13))
          abort
        elseif strcomp(@inStrg, @onLED16)  ' Turn on P16 LED
          hLED          
        elseif strcomp(@inStrg, @offLED16)  ' Turn off P16 LED
          lLED
        elseif strcomp(@inStrg, @teststrg)  ' Get the date from RPi.
          rpi.str(string("date",10,13))
          rpi.RxStr(@inStrg)
          term.str(@inStrg)  ' Print on terminal screen.
        elseif strcomp(@inStrg, @teststrg1)  ' Get the time from RPi.
          rpi.str(string("time",10,13))
          rpi.RxStr(@inStrg)
          term.str(@inStrg)  ' Print on terminal screen.   
        else
          term.str(string("Invalid Command!",10,13))
      

PUB CRLF
  term.Tx(10)
  term.Tx(13)

PUB hLED
  misc.high(16)
  

PUB lLED
  misc.low(16)

'' Cog is started for comm with the Raspberry Pi.
'' For test, turns on/off P16 LED, from a RPi login.
''
PUB talkRPI | inSbyte,inAbyte

    rpi.start(27,25,0,115200)
    misc.waitms(500)

    rpi.str(string("Press CR to continue",10,13))
    repeat
      inSbyte := rpi.Rx
      if inSbyte == 13
        rpi.str(string("Welcome",10,13))
        repeat
          rpi.Tx("%")
          rpi.RxStr(@inStrg)
          if strcomp(@inStrg, @onLED16)
            hLED
          elseif strcomp(@inStrg, @offLED16)
            lLED
          else
            rpi.str(string("Invalid Command!",10,13))


DAT
inStrg byte "               ",0
stopProg byte "Quit",0
onLED16 byte "on16",0
offLED16 byte "off16",0
teststrg byte "date",0
teststrg1 byte "time",0

Comments

  • RsadeikaRsadeika Posts: 3,837
    edited 2015-06-12 09:00
    I decided to rework the program a little when I added the sht11 code. The program bellow works, BUT, a little bug, I think, crept in, and I cannot figure out what is causing it. When I type in 'rawtemp', I am getting a float number representing the temperature, and not a four digit number as to what the sht11 module provides. Sometimes the program starts out showing the four digit number, with 'rawtemp', and then when I do a couple of more readings, it switches to a float number. I hope somebody can help, I just can not find it.

    Ray

    '' tester.spin
    CON
      _clkmode   = xtal1 + pll16x                           
      _xinfreq   = 5_000_000
    
    ' Sensirion sht11 pins
    SHT_DATA  = 1
    SHT_CLOCK = 3 
    
    OBJ
      term : "Extended_FDSerial"  
      misc : "tools"
      sht  : "Sensirion"
      fp   : "FloatString"
      f    : "Float32"
    
    VAR
      long shtStack[100]
    
      long Rtemp, Rhumid, gtempF, Grh, Ctemp ' Global variables
      
    PUB Start
    '            Rx Tx         On QS board
      term.start(26,24,0,9600)
      misc.waitms(500)
      cognew(Sensirion, @shtStack)
      
      main
    
    PUB main | inSbyte,inAbyte
      
      term.str(string("Press CR to continue",10,13))  
      repeat
        inSbyte := term.Rx
        if inSbyte == 13
          term.str(string("Welcome",10,13))
          repeat
            term.Tx("#")
            term.RxStr(@inStrg)
            if strcomp(@inStrg,@stopProg)
              term.str(@inStrg)
              CRLF
              term.str(string("Program Stopped!",10,13))  ' Quit
              abort
            elseif strcomp(@inStrg,@SRawTemp)  ' rawtemp
              term.str(string("RawTemp:"))
              term.str(Rtemp)
              CRLF
            elseif strcomp(@inStrg,@SRawHumid)  ' rawhumid
              term.str(string("RawHumidity:"))
              term.str(Rhumid)
              CRLF
            elseif strcomp(@inStrg,@SGtempf)  ' tempf
              term.str(string("TempF:"))
              term.str(gtempF)
              CRLF
            else
              term.str(string("Unknown Command!",10,13))  
    '    term.str(string("RawTemp"))
    '    term.str(Rtemp)
    '    term.str(string(" ",10,13))
    '    misc.waitms(2000)
    
    PUB Sensirion | rawTemp, rawHumidity, tempC, rh, dewC
      f.start
      misc.waitms(250) 
      sht.start(SHT_DATA, SHT_CLOCK)
    
    
    '  term.str(string("Welcome",10,13))
      repeat
    '    term.str(string(10,13,"RawTemp:"))
        rawTemp := f.FFloat((sht.readTemperature) - 257) ' Local calibration
        Rtemp :=  fp.FloatToFormat(rawTemp, 5, 0)
    '    term.str(fp.FloatToFormat(rawTemp, 5, 0))
    '    term.str(string("   RawHumidity:"))
        rawHumidity := f.FFloat(sht.readHumidity)
        tempC := celsius(rawTemp)
    '    Ctemp := celsius(rawTemp)
        Rhumid := fp.FloatToFormat(rawHumidity, 5, 0)
    '    term.str(fp.FloatToFormat(rawHumidity, 5, 0))
    '    term.str(string("   TempF:"))
    '    term.str(fp.FloatToFormat(fahrenheit(tempC), 5, 1))
         gtempF := fp.FloatToFormat(fahrenheit(tempC), 5, 1)
    '    term.str(string("   TempC:"))
    '    term.str(fp.FloatToFormat(tempC, 5, 1))
    '    term.str(string("   Humidity:"))
    '    rh := humidity(tempC, rawHumidity)
    '    Grh := rh
    '    term.str(fp.FloatToFormat(rh, 5, 1))        
        misc.waitms(1000)
    
    PUB celsius(t)
      ' from SHT1x/SHT7x datasheet using value for 3.5V supply
      ' celsius = -39.66 + (0.01 * t)
      return f.FAdd(-39.66, f.FMul(0.01, t)) 
    
    PUB fahrenheit(t)
      ' fahrenheit = (celsius * 1.8) + 32
      return f.FAdd(f.FMul(t, 1.8), 32.0)
      
    PUB humidity(t, rh) | rhLinear
      ' rhLinear = -4.0 + (0.0405 * rh) + (-2.8e-6 * rh * rh)
      ' simplifies to: rhLinear = ((-2.8e-6 * rh) + 0.0405) * rh -4.0
      rhLinear := f.FAdd(f.FMul(f.FAdd(0.0405, f.FMul(-2.8e-6, rh)), rh), -4.0)
      ' rhTrue = (t - 25.0) * (0.01 + 0.00008 * rawRH) + rhLinear
      return f.FAdd(f.FMul(f.FSub(t, 25.0), f.FAdd(0.01, f.FMul(0.00008, rh))), rhLinear)
    
    PUB dewpoint(t, rh) | h
      ' h = (log10(rh) - 2.0) / 0.4343 + (17.62 * t) / (243.12 + t)
      h := f.FAdd(f.FDiv(f.FSub(f.log10(rh), 2.0), 0.4343), f.FDiv(f.FMul(17.62, t), f.FAdd(243.12, t)))
      ' dewpoint = 243.12 * h / (17.62 - h)
      return f.FDiv(f.FMul(243.12, h), f.FSub(17.62, h))
      
    PUB printRawValues
      term.hex(sht.readStatus, 2)
      term.str(string(", "))
      term.dec(sht.readTemperature)
      term.str(string(", "))
      term.dec(sht.readHumidity)
    
    
    PUB CRLF
      term.Tx(10)
      term.Tx(13)
    
    DAT
    inStrg byte "               ",0
    stopProg byte "Quit",0
    SRawTemp byte  "rawtemp",0
    SRawHumid byte "rawhumid",0
    SGtempf byte "tempf",0  
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-06-12 12:19
    While looking for the bug, I just noticed that 'rawtemp', 'rawhumid', 'tempf' are showing the same value when called. Now I am really scratching my head on this one. I first started out by having the Sensirion program in main, and everything checked out fine, the problem came about when I moved the Sensirion program to its own COG. I wonder if there is something in the Sensirion program that reacts in a strange way when it is run in a cognew? Just throwing some thoughts out there, not sure how to work any further without first resolving this strange action.

    Ray
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-06-12 12:46
    So when you type "rawtemp" your code will execute the line "term.str(RTemp)", which prints out the string located at the address contained in the variable "RTemp".

    The address in RTemp is set by the cog running the Sensirion method. Specifically, it is set by the instruction "Rtemp := fp.FloatToFormat(rawTemp, 5, 0)". I've never used this object, but I assume it is converting a floating point number to a formatted string. FloatToFormat probably contains only one string buffer, so when you call it multiple times in the repeat loop you are over writing it with other formatted numbers.

    You should copy the string to a unique buffer for each instance that you call FloatToFormat so they don't get overwritten.
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-06-12 13:39
    Thanks Dave, I do not know how to resolve the issue that you mentioned, so I worked out the "bug" by reworking the code as shown below. The only drawback is there is a slight hesitation for showing the "#" symbol, and that should stay constant because the Sensirion reading time should not change. Now I can add back in the comm with the RPi code, and work out some preliminary data logging. It should be interesting to see if I can get to read the Sensirion data from the RPi and have it data logged to a file which would include a date and time.

    I kind of like this new concept, saves a COG, with a slight drawback on some hesitation for showing a "#" symbol.

    Ray
    '' tester1.spin
    CON
      _clkmode   = xtal1 + pll16x                           
      _xinfreq   = 5_000_000
    
    ' Sensirion sht11 pins on QS board
    SHT_DATA  = 1
    SHT_CLOCK = 3 
    
    OBJ
      term : "Extended_FDSerial"  
      misc : "tools"
      sht  : "Sensirion"
      fp   : "FloatString"
      f    : "Float32"
    
    VAR
    
      
    PUB Start
    '            Rx Tx         On QS board
      term.start(26,24,0,9600)  'XBee
      
      main
    
    PUB main | rawTemp, rawHumidity, tempC, rh, dewC, inSbyte, inAbyte
      f.start
     
      sht.start(SHT_DATA, SHT_CLOCK)
    
    term.str(string("Press CR to continue",10,13))
    repeat
      inSbyte := term.Rx
      if inSbyte == 13
        term.str(string("Welcome",10,13))  
      repeat    ' Cycles sht11 readings
    '    term.str(string(10,13,"RawTemp:"))
        rawTemp := f.FFloat((sht.readTemperature) - 257) ' Local calibration
    '    Rtemp :=  fp.FloatToFormat(rawTemp, 5, 0)
    '    term.str(fp.FloatToFormat(rawTemp, 5, 0))
    '    term.str(string("   RawHumidity:"))
        rawHumidity := f.FFloat(sht.readHumidity)
        tempC := celsius(rawTemp)
    '    Ctemp := celsius(rawTemp)
    '    term.str(fp.FloatToFormat(rawHumidity, 5, 0))
    '    term.str(string("   TempF:"))
    '    term.str(fp.FloatToFormat(fahrenheit(tempC), 5, 1))
    '    term.str(string("   TempC:"))
    '    term.str(fp.FloatToFormat(tempC, 5, 1))
    '    term.str(string("   Humidity:"))
        rh := humidity(tempC, rawHumidity)
    '    term.str(fp.FloatToFormat(rh, 5, 1)) 
    '' This is the UI portion
            term.Tx("#")
            term.RxStr(@inStrg)
            if strcomp(@inStrg,@stopProg)
              term.str(@inStrg)
              CRLF
              term.str(string("Program Stopped!",10,13))  ' Quit
              abort
            elseif strcomp(@inStrg,@SRawTemp)  ' rawtemp
              term.str(string("RawTemp:"))
              term.str(fp.FloatToFormat(rawTemp, 5, 0))
              CRLF
            elseif strcomp(@inStrg,@SRawHumid)  ' rawhumid
              term.str(string("RawHumidity:"))
              term.str(fp.FloatToFormat(rawHumidity, 5, 0))
              CRLF
            elseif strcomp(@inStrg,@SGtempf)  ' tempf
              term.str(string("TempF:"))
              term.str(fp.FloatToFormat(fahrenheit(tempC), 5, 1))
              CRLF
            elseif strcomp(@inStrg,@SRhunid)
              term.str(string("Humidity:"))
              term.str(fp.FloatToFormat(rh, 5, 1))
              CRLF
            else
              term.str(string("Unknown Command!",10,13))
    
    
    PUB celsius(t)
      ' from SHT1x/SHT7x datasheet using value for 3.5V supply
      ' celsius = -39.66 + (0.01 * t)
      return f.FAdd(-39.66, f.FMul(0.01, t)) 
    
    PUB fahrenheit(t)
      ' fahrenheit = (celsius * 1.8) + 32
      return f.FAdd(f.FMul(t, 1.8), 32.0)
      
    PUB humidity(t, rh) | rhLinear
      ' rhLinear = -4.0 + (0.0405 * rh) + (-2.8e-6 * rh * rh)
      ' simplifies to: rhLinear = ((-2.8e-6 * rh) + 0.0405) * rh -4.0
      rhLinear := f.FAdd(f.FMul(f.FAdd(0.0405, f.FMul(-2.8e-6, rh)), rh), -4.0)
      ' rhTrue = (t - 25.0) * (0.01 + 0.00008 * rawRH) + rhLinear
      return f.FAdd(f.FMul(f.FSub(t, 25.0), f.FAdd(0.01, f.FMul(0.00008, rh))), rhLinear)
    
    PUB dewpoint(t, rh) | h
      ' h = (log10(rh) - 2.0) / 0.4343 + (17.62 * t) / (243.12 + t)
      h := f.FAdd(f.FDiv(f.FSub(f.log10(rh), 2.0), 0.4343), f.FDiv(f.FMul(17.62, t), f.FAdd(243.12, t)))
      ' dewpoint = 243.12 * h / (17.62 - h)
      return f.FDiv(f.FMul(243.12, h), f.FSub(17.62, h))
      
    PUB printRawValues
      term.hex(sht.readStatus, 2)
      term.str(string(", "))
      term.dec(sht.readTemperature)
      term.str(string(", "))
      term.dec(sht.readHumidity)
    
    
    PUB CRLF
      term.Tx(10)
      term.Tx(13)
    
    DAT
    inStrg byte "               ",0
    stopProg byte "Quit",0
    SRawTemp byte  "rawtemp",0
    SRawHumid byte "rawhumid",0
    SGtempf byte "tempf",0
    SRhunid byte "humid",0 
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-06-13 05:05
    Below is a little snippet that compiles but is not working as expected. What I am trying to do is have the Sensirion related code repeat until there is some key press made, in other words a command typed in. So far all I get is "Welcome" when I key in a command. Not sure how to achieve what I need.

    Since I will be adding a comm with the RPi, I need to have a continuous update of the Sensirion data, plus a continuous update will also help in the main pub. I will also implement the global 'Rtemp := fp.FloatToFormat(rawTemp, 5, 0)' and deal with the buffer overwrite, if there is such a occurrence, when I make a command request from the RPi program. If there is no solution using this strategy then I guess I will have to go back to putting the Sensirion code back into its own COG.

    Ray

    term.str(string("Press CR to continue",10,13))
    repeat
      inSbyte := term.Rx
      if inSbyte == 13
        term.str(string("Welcome",10,13))  
      repeat while term.RxStrTime(300,@inStrg) < 0  ' Cycles sht11 readings
    '     term.RxStrTime(200,@inStrg)
    '    term.str(string(10,13,"RawTemp:"))
        rawTemp := f.FFloat((sht.readTemperature) - 257) ' Local calibration
    '    Rtemp :=  fp.FloatToFormat(rawTemp, 5, 0)
    '    term.str(fp.FloatToFormat(rawTemp, 5, 0))
    '    term.str(string("   RawHumidity:"))
        rawHumidity := f.FFloat(sht.readHumidity)
        tempC := celsius(rawTemp)
    '    Ctemp := celsius(rawTemp)
    '    term.str(fp.FloatToFormat(rawHumidity, 5, 0))
    '    term.str(string("   TempF:"))
    '    term.str(fp.FloatToFormat(fahrenheit(tempC), 5, 1))
    '    term.str(string("   TempC:"))
    '    term.str(fp.FloatToFormat(tempC, 5, 1))
    '    term.str(string("   Humidity:"))
        rh := humidity(tempC, rawHumidity)
    '    term.str(fp.FloatToFormat(rh, 5, 1)) 
    '' This is the UI portion
            term.Tx("#")
    '        term.RxStr(@inStrg)
    '    term.RxStrTime(200,@inStrg)
         misc.waitms(250)   
            if strcomp(@inStrg,@stopProg)
              term.str(@inStrg)
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-06-15 07:46
    Since I was having so much trouble with the Spin coding, I switched over to PropGCC and SimpleIDE. In the program below, I am testing to see if I would run into any problems getting sht11 data from a running COG, using global data designations, so far so good. The program below is working as expected. One problem to work out is, how do I display values with a decimal point using the simpletools lib? I would hate to add overhead by using something like printf().

    The C Sensirion sht11 code, that I am using, was developed by tdlivings, which has not been around lately,the program is working as expected. I will have to study the code some more to see what other sht11 data I can extract and use. After I do some more testing and add some more functionality, I will attach a "zip project".

    To switch over to a Propeller HAT, a few problems have to be worked out. The PropellerIDE 0.9.45 version for the Raspberry Pi, does not have the cog_run() functionality, does not work with /dev/ttyAMA0 properly, and ...

    The Propeller HAT itself will have to have an EEPROM available, cannot see loading the program every time. This should not be to big of a problem since the breadboard has enough room for the EEPROM, sht11 module, and an XBee module, I think. Now onto adding some functionality like talking to the RPi to get real time and date values.

    Ray
    /*
      xsensor.c
    
      June 15,2015
      Testing with a QuickStart board, XBee module, sht11 module and RPi.
    */
    #include "simpletools.h"
    #include "simpletext.h"
    #include "fdserial.h"
    #include "sht11.h"
    
    serial *rpi;
    serial *xbee;
    
    /* Sesirion sht11 pins for QS board. */
    int  DatPin = 1;
    int  ClkPin = 3;
    
    sht11values_t MyVals;
    sht11values_t *pMyVals;
    
    volatile long Hum;
    volatile long TmpC;
    volatile long TmpF;
    volatile long Status;
    /***********************/
    
    /* Declare functions */
    void xbeeTalk();   // New COG
    void Sensirion();  // New COG
    void xbmenu();
    
    /* Main comms with the RPi. */
    int main()
    {
      // Add startup code here.
      cog_run(xbeeTalk,128);   // Start the XBee COG.
      pause(200);
      cog_run(Sensirion,128);  // Start the sht11 COG.
      pause(200);
     
      while(1)
      {
        // Add main loop code here.
        high(23);
        pause(700);
        low(23);
        pause(700);
      }  
    }
    
    
    /* XBee COG */
    /* Remote comms with the QS board. */
    void xbeeTalk()
    {
      high(20);
    /*                     Rx Tx         */
      xbee = fdserial_open(27,25,0,9600);  // Pins for QS board
      pause(50);
      
      char inBuff[40];
      while(1)
      {
        writeStr(xbee,"#");
        readStr(xbee, inBuff, 40);
        if(!strcmp(inBuff, "help")) xbmenu();
        else if(!strcmp(inBuff, "tempf"))
        {
          writeStr(xbee,"Temperature: ");
          writeDec(xbee,TmpF/10);
          writeStr(xbee,"F\n");
        }
        else if(!strcmp(inBuff, "humid"))
        {
          writeStr(xbee,"Humidity: ");
          writeDec(xbee,Hum/10);
          writeStr(xbee,"%\n");
        }
        else if(!strcmp(inBuff, "tempc"))
        {
          writeStr(xbee,"Temperature: ");
          writeDec(xbee,TmpC/10);
          writeStr(xbee,"C\n");
        }                
        else
        {
          writeLine(xbee,"Unknown Command");  // Has CR
        }     
    //    high(16);
    //    pause(500);
    //    low(16);
    //    pause(500);  
      }    
    }
    
    void xbmenu()
    {
      writeStr(xbee, "Menu - help, tempf, tempc, humid \n");  
    }
    
    /* Sensirion sht11 COG */
    /* Drives the Sensirion sht11 every second for data refresh module. */
    void Sensirion()
    {
    // Moved to global declare area.
    //long Hum;
    //long TmpC;
    //long TmpF;
    //long Status;
    
      // Add startup code here.
      // Assign the address of our structure to the pointer
      pMyVals = &MyVals;
      high(16);
      pause(1000);
      Start(DatPin,ClkPin,pMyVals);
      Status = ReadStatusReg();  
      while(1)
      {
        Measure();
        Hum = pMyVals->rhlin;   // % Humidity
        TmpC = pMyVals->tempC;  // C degrees
        TmpF = pMyVals->tempF;  // F degrees
        pause(1000);    
    
      }  
    }
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-06-19 04:34
    I took slightly different approach with the SimpleIDE PropGCC program below. So far it is working as expected on the Propeller side and the Raspberry Pi side. My thinking was to use the Propeller for what it was designed for, device/sensor handler, then deal with the data output data as you wish, in this case a unit that will work better for all the data logging requirements.

    A trade off with the program below, I am using sprintf(), which has pushed the program size to 18,792 bytes. Maybe somebody knows of a smaller code size solution for this.

    At this point I am very pleased that the sht11 code is behaving when it is running in its own COG. This program is probably not for beginners, since I did have to use the Project Manager portion of SimpleIDE for some aspects of this project.

    So far, as a Proof-of-Concept trial, it is working as expected. We shall see what happens when other devices/sensors get added to the mix. Will the Propeller be up to the job, from a memory/ COG availability aspect.

    Ray


    /*
      testterm.c
    
      June 18, 2015
      Code placed in Public Domain.  
      A device/sensor handler for the Raspberry Pi.
      Start out with a Sensirion sht11 module from Parallax.
      Moved to a DNA-RTC board for better voltage handling.
      Prototype for eventual(maybe) switch to a Propeller HAT.
      Things that may be added:
        -XBee module
        -DS18B20 temperature sensor, multiple modules.
        -CO2 sensor
        -How much can the Propeller HAT support?
    */
    #include "simpletools.h"
    #include "simpletext.h"
    #include "fdserial.h"
    #include "sht11.h"
    
    serial *rpi;
    
    /* Sensirion sht11 pins */
    int  DatPin = 1;
    int  ClkPin = 3;
    
    sht11values_t MyVals;
    sht11values_t *pMyVals;
    
    volatile long Hum;
    volatile long TmpC;
    volatile long TmpF;
    volatile long Status;
    /***********************/
    
    void Sensirion();  // New COG
    
    int main()
    {
      // Add startup code here.
      cog_run(Sensirion,128);  // Start the sht11 COG.
      pause(200);
      rpi = fdserial_open(19,20,0,115200);  // Raspberry Pi in this case.
      pause(50);
    
      char inBuff[40];
    
      //int message = 9999;  // Debug
      char outBuff[10];
         
      while(1)
      {
        // Add main loop code here.
          readStr(rpi, inBuff, 40);         // Waiting for incoming
          if(!strcmp(inBuff,"gettempf"))        // Checks the string
          {
            //sprintf(outBuff,"%d",message);  // Converts to ascii, Debug
            sprintf(outBuff,"%d",TmpF/10-3); // Use appropriate "%" for data
            writeLine(rpi,outBuff);         // RPi term program understands.
                                            // Sent with CR
          }
          if(!strcmp(inBuff,"gethumid"))
          {
            sprintf(outBuff,"%d",Hum/10);
            writeLine(rpi,outBuff);
          }                
          print("%s\n",inBuff);     // Local Debug         
      }  
    }
    
    /* Sensirion sht11 COG */
    /* Drives the Sensirion sht11 every second for data refresh of module. */
    void Sensirion()
    {
    // Moved to global declare area.
    //long Hum;
    //long TmpC;
    //long TmpF;
    //long Status;
    
      // Add startup code here.
      // Assign the address of our structure to the pointer
      pMyVals = &MyVals;
      high(16);   // Local Debug
      pause(1000);
      Start(DatPin,ClkPin,pMyVals);
      Status = ReadStatusReg();  
      while(1)
      {
        Measure();
        Hum = pMyVals->rhlin;   // % Humidity
        TmpC = pMyVals->tempC;  // C degrees
        TmpF = pMyVals->tempF;  // F degrees
        pause(1000);    
    
      }  
    }
    
    
    /*    Original Debug code, for comm with the freeBasic
          program on the Raspberry Pi.
          // Wait for key press from simpleide terminal
          getStr(locBuff, 40);
          writeLine(rpi,locBuff);  // Send it with CR
          // Displays incoming, up to 40 chars.
          readStr(rpi, inBuff, 40);
          print("%s\n",inBuff); 
    */
    

    This is the freeBasic code that is used on the Raspberry Pi.
    ' xsensor3.bas
    ' June 18, 2015
    '
    ' Serial terminal to work with a Propeller Board.
    ' Code placed in Public Domain. 
    '
    ' Change the ttyAMA0, default is set at 9600 BAUD.
    shell "stty -F /dev/ttyAMA0 115200"
    
    ' Declare global variables
    dim as string buffer,buffer1,inBuff
    dim inBuff1 as single
    
    ' Connect to Propeller board on other end.
    Open Com "/dev/ttyAMA0:115200,n,8,1,cs0,ds0,cd0,rs" as #1
    
    ' Declare Subs
    declare sub menu()
    
    
    ''''' Main '''''
    print "xsensor for the Raspberry Pi"
    print "Type 'help' or '?' for menu."
    print "%";  ' Print initial cursor symbol
    
    do
    
    '' Get the command input
    	buffer = input$(1)          ' Get a keypress
    	buffer1 = buffer1 + buffer  ' Put in buffer
    	print "" & buffer;          ' Print the keypress
    	
    	if buffer = chr$(27) then   ' Check if <Esc> was pressed
    		exit do
    	end if
    	if buffer = chr$(13) then   ' Check if it was a CR
    		buffer1 = rtrim(buffer1,chr$(13))  ' Strip off CR
    		print "%" & buffer1     ' Print the string
    '' Check for commands		
    		if buffer1 = "quit" then
    			exit do
    		elseif buffer1 = "date" then  ' Get todays date
    			print date
    		elseif buffer1 = "time" then  ' Get the real time in 24 hour mode
    			print time
    		elseif buffer1 = "tempf" then  ' Get temperature in F degrees.
    			print #1,"gettempf" & chr$(13)  ' Send to Propeller.
    				sleep 50,0
    				while loc(1) > 0
    					inBuff = input$(loc(1),#1)  'Get data from Propeller
    					'print inBuff;  ' Local Debug
    				wend
    				' Make the data workable.
    				inbuff = ltrim(inBuff,"gettempf")  ' Trim off junk
    				inbuff = ltrim(inBuff,chr$(13))  ' CR
    				inBuff = ltrim(inBuff,chr$(10))  ' LF
    				inBuff = rtrim(inBuff,chr$(13))  ' CR
    				inBuff = rtrim(inBuff,chr$(10))  ' LF				
    				inBuff1 = val(inBuff)  ' Convert string to float number.
    				print "Temperature: ";inBuff1; " F"
    		elseif buffer1 = "humid" then  ' Get humidity.
    			print #1,"gethumid" & chr$(13)  ' Send to Propeller.
    				sleep 50,0
    				while loc(1) > 0
    					inBuff = input$(loc(1),#1)  'Get data from Propeller
    					'print inBuff;  ' Local Debug
    				wend
    				' Make the data workable.
    				inbuff = ltrim(inBuff,"gethumid")  ' Trim off junk
    				inbuff = ltrim(inBuff,chr$(13))  ' CR
    				inBuff = ltrim(inBuff,chr$(10))  ' LF
    				inBuff = rtrim(inBuff,chr$(13))  ' CR
    				inBuff = rtrim(inBuff,chr$(10))  ' LF				
    				inBuff1 = val(inBuff)  ' Convert string to float number.
    				print "Humidity: ";inBuff1; " %"
    		' elseif ... Data logger
    		' elseif ... Data log scheduler ??  ?threaded?
    		' elseif ... Other devices/sensors on the Propeller
    		elseif buffer1 = "help" or buffer1 = "?" then  ' Get the menu.
    			menu()
    		else
    			print "Unknown Command"
    		end if
    		buffer1 = ""  ' Clear buffer1
    		print "%";    ' Print the cursor symbol
    		
    	end if
    	
    
    
    sleep 1,0
    loop
    print "Closing Port(s)"
    close
    print "Program Stopped!"
    sleep 5000,0
    end
    
    
    sub menu()
    	print "Menu - help, quit, time, date, tempf, humid "
    	print "quit or <Esc> ends program."
    end sub
    
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-06-22 14:40
    Since I am now using the DNA-RTC board instead of the QuickStart, I decided to add some code for using the RTC. And I also added XBee in its own cog, so now you can use the sht11 data, plus get the date and time on the Propeller side, after the RTC has been setup. It would be nice if I could get the real time from the RPi and have the DNA-RTC board updated at start up.

    It seems that a small bug has crept in with the xbeeTalk() COG, these two lines are not showing up on the terminal screen at start up of the COG, the rest of the code runs fine. I have not the slightest idea as to why that is occurring. Anybody have an idea?
      writeStr(xbee,"Welcome\n");
      writeLine(xbee,"Type 'help' for menu.");
    

    The next to-do is start adding code for the DS18B20 temperature sensor, I did find some C code for that module in the OBEX, now it is a matter of getting the code to work within this program.

    I have my eye on adding a Parallax Gas Sensor board, but Parallax does not sell a CO2 or O sensors, plus I did not see any C code to work with the board. Anybody have any leads on where to get something like that? Actually I will want to be able to capture the sensor data, and not just set alarm positions.

    So far Code Size is 23,584 bytes.

    Ray
    /*
      testterm.c
    
      June 18, 2015
      Code placed in Public Domain.  
      A device/sensor handler for the Raspberry Pi.
      Start out with a Sensirion sht11 module from Parallax.
      Moved to a DNA-RTC board for better voltage handling.
      Prototype for eventual(maybe) switch to a Propeller HAT.
      Things that may be added:
        -XBee module (added 6/22/15)
        -RTC (added 6/22/15)
        -DS18B20 temperature sensor, multiple modules.
        -CO2 sensor
        -How much can the Propeller HAT support?
    */
    #include "simpletools.h"
    #include "simpletext.h"
    #include "fdserial.h"
    #include "sht11.h"
    #include "basic_i2c_driver.h"
    #include "sRTC.h"
    
    #define BUFFERLEN 10
    
    serial *rpi;
    serial *xbee;
    
    /* Sensirion sht11 pins */
    int  DatPin = 1;
    int  ClkPin = 3;
    
    sht11values_t MyVals;
    sht11values_t *pMyVals;
    
    volatile long Hum;
    volatile long TmpC;
    volatile long TmpF;
    volatile long Status;
    /***********************/
    
    void Sensirion();  // New COG
    void talkXBee();
    
    int prompttime(char *prompt);
    void Set_Clock();
    void GetTime();
    void GetTD();
    void Set_Time();
    void xbeeHelp();
    
    int main()
    {
      // Add startup code here.
      cog_run(talkXBee,256);
      pause(50);
      cog_run(Sensirion,128);  // Start the sht11 COG.
      pause(200);
    /*                     Rx Tx         */
      rpi = fdserial_open(19,20,0,115200);  // Raspberry Pi in this case.
      pause(50);
    
      char inBuff[40];
    
      //int message = 9999;  // Debug
      char outBuff[10];
         
      while(1)
      {
        // Add main loop code here.
          readStr(rpi, inBuff, 40);         // Waiting for incoming
          if(!strcmp(inBuff,"gettempf"))        // Checks the string
          {
            //sprintf(outBuff,"%d",message);  // Converts to ascii, Debug
            sprintf(outBuff,"%d",TmpF/10-3); // Use appropriate "%" for data
            writeLine(rpi,outBuff);         // RPi term program understands.
                                            // Sent with CR
          }
          if(!strcmp(inBuff,"gethumid"))
          {
            sprintf(outBuff,"%d",Hum/10);
            writeLine(rpi,outBuff);
          }                
          print("%s\n",inBuff);     // Local Debug         
      }  
    }
    
    /* XBee comms COG */
    void talkXBee()
    {
      /*                     Rx Tx         */
      xbee = fdserial_open(17,18,0,9600);
      pause(250);
    /* These two lines are not showing up at start up ??? */
      writeStr(xbee,"Welcome\n");
      writeLine(xbee,"Type 'help' for menu.");
      ///////////////  
      sRTC_Start();
      
      sRTC_Update();
      sRTC_Set24hourmode(1);
      sRTC_Update();
    
    
      //pause(1000);
      writeStr(xbee,"#");   // This is not shwoing up at startup ??? ////
      char inBuff[40];
      
      while(1)
      {
        writeStr(xbee,"#");
        readStr(xbee, inBuff, 40);
        if(!strcmp(inBuff,"tempf"))
        {
          writeStr(xbee,"Temperature: ");
          writeDec(xbee,((TmpF/10)-3));
          writeLine(xbee," F");
        }
        else if(!strcmp(inBuff,"humid"))
        {
          writeStr(xbee,"Humidity: ");
          writeDec(xbee,Hum/10);
          writeLine(xbee,"%");
        }
        else if(!strcmp(inBuff,"setclock"))
        {
          writeLine(xbee,"Month,Day,Year XX,dow,Hour,Minutes,Seconds\n");
          writeLine(xbee,"dow: 0-Sun,1-Mon,2-Tue,3-Wed,4-Thu,5-Fri,6-Sat\n");
          Set_Clock();
        }
        else if(!strcmp(inBuff,"time"))
        {
          GetTime();
        }
        else if (!strcmp(inBuff, "date"))
        {
          GetTD();
        }
        else if (!strcmp(inBuff, "settime"))
        {
          writeLine(xbee,"Hour,Minute,Second");
          Set_Time();
        }
        else if(!strcmp(inBuff, "help"))
        {
          xbeeHelp();
        }                  
        else
        {
          writeLine(xbee,"Unknown Command");
        }            
      }      
      
    }
    
    
    int prompttime(char *prompt)
    {
        int rc = 0;
        char *endp;
        char buffer[BUFFERLEN];
        
        do {
            dprinti(xbee,"Enter %s:  ",prompt);
            readStr(xbee, buffer, 10);
            rc = strtol(buffer, &endp, 10);
            if(endp == buffer)
            {
              if('\n' == *endp)
              {
                rc = 0;
                break;
              }
              dprinti(xbee,"Invalid entry \"%c.....\" Please enter a number.\n",*endp);           
            }          
          
        } while (endp == buffer);
        return rc;
    }
    
    void Set_Clock()
    {
        int month,day,year,dow,hour,minute,second;
        month = prompttime("Month");
        day = prompttime("Day");
        year = prompttime("Year");
        dow = prompttime("DayOfWeek");
        hour = prompttime("Hour");
        minute = prompttime("Minute");
        second = prompttime("Second");
        
        dprinti(xbee,"\n%d %d %d %d %d %d %d\n",month,day,year,dow,hour,minute,second);
        sRTC_Setdatetime(month,day,year,dow,hour,minute,second);
        sRTC_Update();        // This is neccessary
    }
    
    void GetTime()
    {
        int result, result1, result2;
        sRTC_Update();  // This is neccessary
        result = sRTC_Gethour();
        result1 = sRTC_Getminutes();
        result2 = sRTC_Getseconds();
        dprinti(xbee,"%d:%d:%d\n",result,result1,result2);  
    }
    
    void GetTD()
    {
        int result, result1, result2;
        sRTC_Update();   // This is neccessary
        result = sRTC_Getmonth();
        result1 = sRTC_Getday();
        result2 = sRTC_Getyear();
        dprinti(xbee,"%d/%d/%d\n",result,result1,result2);  
    }
    
    void Set_Time()
    {
        int hour,minute,second;
        hour = prompttime("Hour");
        minute = prompttime("Minute");
        second = prompttime("Second");
        dprinti(xbee,"\n%d %d %d\n",hour,minute,second);
        sRTC_Settime(hour,minute,second);
        sRTC_Update();  
    }
    
    void xbeeHelp()
    {
      writeLine(xbee,"Menu - help, tempf, humid, setclock, settime");
      writeLine(xbee,"       time, date ");
    }        
       
      
    /**************************************/
    /* Sensirion sht11 COG */
    /* Drives the Sensirion sht11 every second for data refresh of module. */
    void Sensirion()
    {
    // Moved to global declare area.
    //long Hum;
    //long TmpC;
    //long TmpF;
    //long Status;
    
      // Add startup code here.
      // Assign the address of our structure to the pointer
      pMyVals = &MyVals;
      high(16);   // Local Debug
      pause(1000);
      Start(DatPin,ClkPin,pMyVals);
      Status = ReadStatusReg();  
      while(1)
      {
        Measure();              // Get data from sht11 module.
        Hum = pMyVals->rhlin;   // % Humidity
        TmpC = pMyVals->tempC;  // C degrees
        TmpF = pMyVals->tempF;  // F degrees
        pause(1000);            // Pause for one second.
    
      }  
    }
    
    
    /*    Original Debug code, for comm with the freeBasic
          program on the Raspberry Pi.
          // Wait for key press from simpleide terminal
          getStr(locBuff, 40);
          writeLine(rpi,locBuff);  // Send it with CR
          // Displays incoming, up to 40 chars.
          readStr(rpi, inBuff, 40);
          print("%s\n",inBuff); 
    */
    
  • twm47099twm47099 Posts: 867
    edited 2015-06-22 16:27
    Ray
    If you are only working with integers you can use sprinti () instead of sprintf (). That would save about 10k memory.

    Tom
  • RsadeikaRsadeika Posts: 3,837
    edited 2015-06-23 05:10
    Thanks for the suggestion Tom. Before I implemented sprintf(), I also tried sprinti(), the code difference between the two was about 100 bytes with sprintf() coming in smaller, at compile time. As far as total compile time size, there was no major size reduction, did not see a 10k size reduction, so I went with sprintf().

    I am still undecided as to what accuracy I want my sht11 data to be, so I am still looking into the C driver code for the sht11 module. After a quick look see I noticed that all the variables were designated as 'long' type, now I am not so sure that it would be an easy fix to get 'float' data, without a major rewrite. I guess if one of the professional C coders would look at the program it would be much appreciated.

    So where is all this heading, I still have to do more proofing, before I make a final decision. I started out with the QuickStart board and have switched over to the DNA-RTC board. It seems that the voltage distribution problems have disappeared. I am still thinking about a Propeller HAT type solution, but there are still some problems to overcome, my perception of course. I am making a mental note, but I get the impression that everybody thinks I am bashing the product(s), when I list them all. In my opinion, these products are no longer in Alpha state, or at least I thought so, I will just have to work around the obstacles to get too where I need to be.

    Now that I tried both Spin and C, for the same program solution, I feel more confidant with using C to get what I want in a timely fashion. I am sure that some Spin coders are shaking there heads in disagreement, but I like to go with what I think I know, this not a slam against Spin. I think that if I had something like a freeBasic program for the Propeller, I would probably go with that instead of C, more heads shaking. No flame wars please.

    Ray
Sign In or Register to comment.