Author Topic: SLA  (Read 625 times)

0 Members and 1 Guest are viewing this topic.

John

  • Hero Member
  • *****
  • Posts: 3639
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: (sb) [Select]
' DHT11 - WiringPi Interface

IMPORT wpi.bas

WPI::wiringPiSetup()

valid = 0
samples = 0

WHILE valid = 0

  SPLITA "00000" BY "" TO dht11_dat
  laststate = 1
  counter = 0
  j = 0

  WPI::pinMode(7, 1)
  WPI::digitalWrite(7, 0)
  WPI::msSleep(18)
  WPI::digitalWrite(7, 1)
  WPI::msSleep(40)
  WPI::pinMode(7, 0)
  FOR i = 0 TO 85
    counter = 0
    WHILE WPI::digitalRead(7) = laststate
      counter += 1
      WPI::msSleep(1)
      IF counter = 255 THEN GOTO EXIT_WHILE
    WEND
    EXIT_WHILE:     
    laststate = WPI::digitalRead(7)
    IF counter = 255 THEN GOTO EXIT_NEXT
    IF i >= 4 AND i % 2 = 0 THEN
      dht11_dat[j / 8] = dht11_dat[j / 8] * 2
      IF counter > 50 AND EVEN(dht11_dat[j / 8]) THEN
        dht11_dat[j / 8] += 1
        j += 1
      END IF
    END IF
  NEXT
  EXIT_NEXT:
  IF j >= 40 AND dht11_dat[4] = (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) % 0xFF THEN
    PRINT FORMAT("Humidity: %.1f %%\n", dht11_dat[0] + (dht11_dat[1] * .1))
    PRINT FORMAT("Temperature: %.1f C\n", dht11_dat[2] + (dht11_dat[3] * .1))
    samples += 1 
    PRINT "Samples: ", samples, "\n"
    valid = 1
  END IF
  WPI::msSleep(1500)
  PRINT "<Sample Error>\n"
  samples += 1 
WEND


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

Code: (c) [Select]
besFUNCTION(DHT11)
  int pin;
  VARIABLE Argument1;

  besARGUMENTS("i")
    &pin
  besARGEND

  VARIABLE Argument2;
  VARIABLE Argument3;
  unsigned long __refcount_;
  LEFTVALUE Lval2;
  LEFTVALUE Lval3;

  Argument2 = besARGUMENT(2);
  besLEFTVALUE(Argument2,Lval2);
  besRELEASE(*Lval2);
  *Lval2 = NULL;

  Argument3 = besARGUMENT(3);
  besLEFTVALUE(Argument3,Lval3);
  besRELEASE(*Lval3);
  *Lval3 = NULL;

  *Lval2 = besNEWDOUBLE;
  *Lval3 = besNEWDOUBLE;

  wiringPiSetup();

  int valid = 0;
  int samples = 0;

while(valid == 0)
 {
  int dht11_dat[5] = { 0, 0, 0, 0, 0 };
  uint8_t laststate = HIGH;
  uint8_t counter   = 0;
  uint8_t j   = 0, i;
  float f; /* fahrenheit */
  dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;

  /* pull pin down for 18 milliseconds */
  pinMode( pin, OUTPUT );
  digitalWrite( pin, LOW );
  delay( 18 );
  /* then pull it up for 40 microseconds */
  digitalWrite( pin, HIGH );
  delayMicroseconds( 40 );
  /* prepare to read the pin */
  pinMode( pin, INPUT );

  /* detect change and read data */
  for ( i = 0; i < MAXTIMINGS; i++ )
  {
    counter = 0;
    while ( digitalRead( pin ) == laststate )
    {
      counter++;
      delayMicroseconds( 1 );
      if ( counter == 255 )
      {
        break;
      }
    }
    laststate = digitalRead( pin );

    if ( counter == 255 )
      break;

    /* ignore first 3 transitions */
    if ( (i >= 4) && (i % 2 == 0) )
    {
      /* shove each bit into the storage bytes */
      dht11_dat[j / 8] <<= 1;
/*      if ( counter > 16 ) */
      if ( counter > 50 )
        dht11_dat[j / 8] |= 1;
      j++;
    }
  }

  /*
   * check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
   * print it out if data is good
   */
  if ( (j >= 40) &&
       (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) )
  {
    f = dht11_dat[2] * 9. / 5. + 32;
    DOUBLEVALUE(*Lval2) = dht11_dat[0] + (dht11_dat[1] * .1);
    DOUBLEVALUE(*Lval3) = dht11_dat[2] + (dht11_dat[3] * .1);
    samples = samples + 1;
    valid = 1;
  }
  delay( 1500 );
  samples = samples + 1;
 }
  besRETURN_LONG(samples);
besEND


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

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4267
    • 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: 3639
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: 4267
    • 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: 3639
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: 1993
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)