Author Topic: SLA  (Read 207 times)

0 Members and 1 Guest are viewing this topic.

John

  • Hero Member
  • *****
  • Posts: 3600
SLA
« on: June 04, 2019, 11:46:53 AM »
Here is the ScriptBasic WiringPi interface for the DHT11 humidity and temperature sensor.

Any help or suggestions would be appreciated getting the couple lines in question converted properly.


Code: Script BASIC
  1. ' DHT11 - WiringPi Interface
  2.  
  3. IMPORT wpi.bas
  4.  
  5. WPI::wiringPiSetup()
  6.  
  7. valid = 0
  8. samples = 0
  9.  
  10. WHILE valid = 0
  11.  
  12.   SPLITA "00000" BY "" TO dht11_dat
  13.   laststate = 1
  14.   counter = 0
  15.   j = 0
  16.  
  17.   WPI::pinMode(7, 1)
  18.   WPI::digitalWrite(7, 0)
  19.   WPI::msSleep(18)
  20.   WPI::digitalWrite(7, 1)
  21.   WPI::msSleep(40)
  22.   WPI::pinMode(7, 0)
  23.   FOR i = 0 TO 85
  24.     counter = 0
  25.     WHILE WPI::digitalRead(7) = laststate
  26.       counter += 1
  27.       WPI::msSleep(1)
  28.       IF counter = 255 THEN GOTO EXIT_WHILE
  29.     WEND
  30.     EXIT_WHILE:      
  31.     laststate = WPI::digitalRead(7)
  32.     IF counter = 255 THEN GOTO EXIT_NEXT
  33.     IF i >= 4 AND i % 2 = 0 THEN
  34.       dht11_dat[j / 8] = dht11_dat[j / 8] * 2
  35.       IF counter > 50 AND EVEN(dht11_dat[j / 8]) THEN
  36.         dht11_dat[j / 8] += 1
  37.         j += 1
  38.       END IF
  39.     END IF
  40.   NEXT
  41.   EXIT_NEXT:
  42.   IF j >= 40 AND dht11_dat[4] = (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) % 0xFF THEN
  43.     PRINT FORMAT("Humidity: %.1f %%\n", dht11_dat[0] + (dht11_dat[1] * .1))
  44.     PRINT FORMAT("Temperature: %.1f C\n", dht11_dat[2] + (dht11_dat[3] * .1))
  45.     samples += 1  
  46.     PRINT "Samples: ", samples, "\n"
  47.     valid = 1
  48.   END IF
  49.   WPI::msSleep(1500)
  50.   PRINT "<Sample Error>\n"
  51.   samples += 1  
  52. WEND
  53.  


This is the C version of the code that works in the same extension module as a dedicated function.

Code: C
  1. besFUNCTION(DHT11)
  2.   int pin;
  3.   VARIABLE Argument1;
  4.  
  5.   besARGUMENTS("i")
  6.     &pin
  7.   besARGEND
  8.  
  9.   VARIABLE Argument2;
  10.   VARIABLE Argument3;
  11.   unsigned long __refcount_;
  12.   LEFTVALUE Lval2;
  13.   LEFTVALUE Lval3;
  14.  
  15.   Argument2 = besARGUMENT(2);
  16.   besLEFTVALUE(Argument2,Lval2);
  17.   besRELEASE(*Lval2);
  18.   *Lval2 = NULL;
  19.  
  20.   Argument3 = besARGUMENT(3);
  21.   besLEFTVALUE(Argument3,Lval3);
  22.   besRELEASE(*Lval3);
  23.   *Lval3 = NULL;
  24.  
  25.   *Lval2 = besNEWDOUBLE;
  26.   *Lval3 = besNEWDOUBLE;
  27.  
  28.   wiringPiSetup();
  29.  
  30.   int valid = 0;
  31.   int samples = 0;
  32.  
  33. while(valid == 0)
  34.  {
  35.   int dht11_dat[5] = { 0, 0, 0, 0, 0 };
  36.   uint8_t laststate = HIGH;
  37.   uint8_t counter   = 0;
  38.   uint8_t j   = 0, i;
  39.   float f; /* fahrenheit */
  40.   dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
  41.  
  42.   /* pull pin down for 18 milliseconds */
  43.   pinMode( pin, OUTPUT );
  44.   digitalWrite( pin, LOW );
  45.   delay( 18 );
  46.   /* then pull it up for 40 microseconds */
  47.   digitalWrite( pin, HIGH );
  48.   delayMicroseconds( 40 );
  49.   /* prepare to read the pin */
  50.   pinMode( pin, INPUT );
  51.  
  52.   /* detect change and read data */
  53.   for ( i = 0; i < MAXTIMINGS; i++ )
  54.   {
  55.     counter = 0;
  56.     while ( digitalRead( pin ) == laststate )
  57.     {
  58.       counter++;
  59.       delayMicroseconds( 1 );
  60.       if ( counter == 255 )
  61.       {
  62.         break;
  63.       }
  64.     }
  65.     laststate = digitalRead( pin );
  66.  
  67.     if ( counter == 255 )
  68.       break;
  69.  
  70.     /* ignore first 3 transitions */
  71.     if ( (i >= 4) && (i % 2 == 0) )
  72.     {
  73.       /* shove each bit into the storage bytes */
  74.       dht11_dat[j / 8] <<= 1;
  75. /*      if ( counter > 16 ) */
  76.       if ( counter > 50 )
  77.         dht11_dat[j / 8] |= 1;
  78.       j++;
  79.     }
  80.   }
  81.  
  82.   /*
  83.    * check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
  84.    * print it out if data is good
  85.    */
  86.   if ( (j >= 40) &&
  87.        (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) )
  88.   {
  89.     f = dht11_dat[2] * 9. / 5. + 32;
  90.     DOUBLEVALUE(*Lval2) = dht11_dat[0] + (dht11_dat[1] * .1);
  91.     DOUBLEVALUE(*Lval3) = dht11_dat[2] + (dht11_dat[3] * .1);
  92.     samples = samples + 1;
  93.     valid = 1;
  94.   }
  95.   delay( 1500 );
  96.   samples = samples + 1;
  97.  }
  98.   besRETURN_LONG(samples);
  99. besEND
  100.  


« Last Edit: June 04, 2019, 05:19:16 PM by John »

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4097
    • Oxygen Basic
Re: SLA
« Reply #1 on: June 05, 2019, 12:04:20 AM »
Hi John,

v<<=1
becomes
v*=2

and I'm not sure about SB rounding behaviour so
instead of indexing with [j/8]
this could be precalculated:
k=trunc(j/8)
then use [k]

John

  • Hero Member
  • *****
  • Posts: 3600
Re: SLA
« Reply #2 on: June 05, 2019, 12:57:09 AM »
Thanks Charles!

I'll give your suggestions a try.


Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4097
    • Oxygen Basic
Re: SLA
« Reply #3 on: June 05, 2019, 01:56:20 AM »
correction: SB uses fix() instead of trunc()

John

  • Hero Member
  • *****
  • Posts: 3600
Re: SLA
« Reply #4 on: June 05, 2019, 02:16:11 AM »
I also screwed up trying to use my msSleep() when WiringPi used 2 different delay functions. (milli and micro second)

Quote
You have a millisecond sleep while polling for level changes which can have as little as 26 microseconds between them.

Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1923
Re: SLA
« Reply #5 on: June 05, 2019, 10:03:02 AM »
Quote
You have a millisecond sleep while polling for level changes which can have as little as 26 microseconds between them.

Whose quote was that?

I have a very vague recollection (and I might be wrong and too lazy to verify it myself) of SB's delay functions being highly platform dependent. Under Windows, delay precision is determined by the resolution of Windows system timer (Sleep() WinAPI), which is rather low at approx. 15.6 milliseconds (i.e. 0.0156 of a second) in most cases. OTOH under Linux,  the resolution goes as high as the Linux system timer permits, which may be on the order of microseconds that is millionths of a second, e.g. 15.6 microseconds or 0.0000156 of a second.

I'm not sure which precision is applicable to, or supported on, the Raspberry Pi platform. At any rate, if RPi timing is as coarse as it is under Windows, then delay-based approaches to the events occurring as frequently as ca. 38,500 times per second (i.e. as short in their duration as only 26 Ás/microseconds, or 0.000026 sec each) seem hardly reasonable and are bound to fail.
« Last Edit: June 05, 2019, 10:31:20 AM by Mike Lobanovsky »
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)