Author Topic: SB π  (Read 4546 times)

Offline John

  • Forum Support / SB Dev
  • Posts: 2622
    • ScriptBasic Open Source Project
Re: SB π
« Reply #135 on: April 05, 2019, 03:39:27 PM »
The Sense HAT basicsensor.c program seems to be working.


pi@raspberrypi:~/sbrpi/sensehat $ ./basicsensor
P_LPS25H  mbar      T_HTS221    deg C     H_HTS221    rH
0x2f4800  +756.5    0x005b      +22.403   0xdfeb      +56.698   
pi@raspberrypi:~/sbrpi/sensehat $


This is a Hello World on the LED display.. The same python code works on the emulator and the physical board.

Code: Python
  1. from sense_emu import SenseHat
  2.  
  3. sense = SenseHat()
  4.  
  5. sense.show_message("Hello world!")
  6.  

Changing sense_emu to sense_hat switches between the emulator and the physical board.

i2c-dev.h
Code: C
  1. /*
  2.     i2c-dev.h - i2c-bus driver, char device interface
  3.  
  4.     Copyright (C) 1995-97 Simon G. Vogl
  5.     Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  20.     MA 02110-1301 USA.
  21. */
  22.  
  23. #ifndef _LINUX_I2C_DEV_H
  24. #define _LINUX_I2C_DEV_H
  25.  
  26. #include <linux/types.h>
  27. #include <sys/ioctl.h>
  28. #include <stddef.h>
  29.  
  30.  
  31. /* -- i2c.h -- */
  32.  
  33.  
  34. /*
  35.  * I2C Message - used for pure i2c transaction, also from /dev interface
  36.  */
  37. struct i2c_msg {
  38.         __u16 addr;     /* slave address                        */
  39.         unsigned short flags;
  40. #define I2C_M_TEN       0x10    /* we have a ten bit chip address       */
  41. #define I2C_M_RD        0x01
  42. #define I2C_M_NOSTART   0x4000
  43. #define I2C_M_REV_DIR_ADDR      0x2000
  44. #define I2C_M_IGNORE_NAK        0x1000
  45. #define I2C_M_NO_RD_ACK         0x0800
  46.         short len;              /* msg length                           */
  47.         char *buf;              /* pointer to msg data                  */
  48. };
  49.  
  50. /* To determine what functionality is present */
  51.  
  52. #define I2C_FUNC_I2C                    0x00000001
  53. #define I2C_FUNC_10BIT_ADDR             0x00000002
  54. #define I2C_FUNC_PROTOCOL_MANGLING      0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
  55. #define I2C_FUNC_SMBUS_PEC              0x00000008
  56. #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL  0x00008000 /* SMBus 2.0 */
  57. #define I2C_FUNC_SMBUS_QUICK            0x00010000
  58. #define I2C_FUNC_SMBUS_READ_BYTE        0x00020000
  59. #define I2C_FUNC_SMBUS_WRITE_BYTE       0x00040000
  60. #define I2C_FUNC_SMBUS_READ_BYTE_DATA   0x00080000
  61. #define I2C_FUNC_SMBUS_WRITE_BYTE_DATA  0x00100000
  62. #define I2C_FUNC_SMBUS_READ_WORD_DATA   0x00200000
  63. #define I2C_FUNC_SMBUS_WRITE_WORD_DATA  0x00400000
  64. #define I2C_FUNC_SMBUS_PROC_CALL        0x00800000
  65. #define I2C_FUNC_SMBUS_READ_BLOCK_DATA  0x01000000
  66. #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
  67. #define I2C_FUNC_SMBUS_READ_I2C_BLOCK   0x04000000 /* I2C-like block xfer  */
  68. #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK  0x08000000 /* w/ 1-byte reg. addr. */
  69.  
  70. #define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
  71.                              I2C_FUNC_SMBUS_WRITE_BYTE)
  72. #define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
  73.                                   I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
  74. #define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \
  75.                                   I2C_FUNC_SMBUS_WRITE_WORD_DATA)
  76. #define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
  77.                                    I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
  78. #define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
  79.                                   I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
  80.  
  81. /* Old name, for compatibility */
  82. #define I2C_FUNC_SMBUS_HWPEC_CALC       I2C_FUNC_SMBUS_PEC
  83.  
  84. /*
  85.  * Data for SMBus Messages
  86.  */
  87. #define I2C_SMBUS_BLOCK_MAX     32      /* As specified in SMBus standard */
  88. #define I2C_SMBUS_I2C_BLOCK_MAX 32      /* Not specified but we use same structure */
  89. union i2c_smbus_data {
  90.         __u8 byte;
  91.         __u16 word;
  92.         __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
  93.                                                     /* and one more for PEC */
  94. };
  95.  
  96. /* smbus_access read or write markers */
  97. #define I2C_SMBUS_READ  1
  98. #define I2C_SMBUS_WRITE 0
  99.  
  100. /* SMBus transaction types (size parameter in the above functions)
  101.    Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
  102. #define I2C_SMBUS_QUICK             0
  103. #define I2C_SMBUS_BYTE              1
  104. #define I2C_SMBUS_BYTE_DATA         2
  105. #define I2C_SMBUS_WORD_DATA         3
  106. #define I2C_SMBUS_PROC_CALL         4
  107. #define I2C_SMBUS_BLOCK_DATA        5
  108. #define I2C_SMBUS_I2C_BLOCK_BROKEN  6
  109. #define I2C_SMBUS_BLOCK_PROC_CALL   7           /* SMBus 2.0 */
  110. #define I2C_SMBUS_I2C_BLOCK_DATA    8
  111.  
  112.  
  113. /* /dev/i2c-X ioctl commands.  The ioctl's parameter is always an
  114.  * unsigned long, except for:
  115.  *      - I2C_FUNCS, takes pointer to an unsigned long
  116.  *      - I2C_RDWR, takes pointer to struct i2c_rdwr_ioctl_data
  117.  *      - I2C_SMBUS, takes pointer to struct i2c_smbus_ioctl_data
  118.  */
  119. #define I2C_RETRIES     0x0701  /* number of times a device address should
  120.                                    be polled when not acknowledging */
  121. #define I2C_TIMEOUT     0x0702  /* set timeout in units of 10 ms */
  122.  
  123. /* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses
  124.  * are NOT supported! (due to code brokenness)
  125.  */
  126. #define I2C_SLAVE       0x0703  /* Use this slave address */
  127. #define I2C_SLAVE_FORCE 0x0706  /* Use this slave address, even if it
  128.                                    is already in use by a driver! */
  129. #define I2C_TENBIT      0x0704  /* 0 for 7 bit addrs, != 0 for 10 bit */
  130.  
  131. #define I2C_FUNCS       0x0705  /* Get the adapter functionality mask */
  132.  
  133. #define I2C_RDWR        0x0707  /* Combined R/W transfer (one STOP only) */
  134.  
  135. #define I2C_PEC         0x0708  /* != 0 to use PEC with SMBus */
  136. #define I2C_SMBUS       0x0720  /* SMBus transfer */
  137.  
  138.  
  139. /* This is the structure as used in the I2C_SMBUS ioctl call */
  140. struct i2c_smbus_ioctl_data {
  141.         __u8 read_write;
  142.         __u8 command;
  143.         __u32 size;
  144.         union i2c_smbus_data *data;
  145. };
  146.  
  147. /* This is the structure as used in the I2C_RDWR ioctl call */
  148. struct i2c_rdwr_ioctl_data {
  149.         struct i2c_msg *msgs;   /* pointers to i2c_msgs */
  150.         __u32 nmsgs;                    /* number of i2c_msgs */
  151. };
  152.  
  153. #define  I2C_RDRW_IOCTL_MAX_MSGS        42
  154.  
  155.  
  156. static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,
  157.                                      int size, union i2c_smbus_data *data)
  158. {
  159.         struct i2c_smbus_ioctl_data args;
  160.  
  161.         args.read_write = read_write;
  162.         args.command = command;
  163.         args.size = size;
  164.         args.data = data;
  165.         return ioctl(file,I2C_SMBUS,&args);
  166. }
  167.  
  168.  
  169. static inline __s32 i2c_smbus_write_quick(int file, __u8 value)
  170. {
  171.         return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL);
  172. }
  173.  
  174. static inline __s32 i2c_smbus_read_byte(int file)
  175. {
  176.         union i2c_smbus_data data;
  177.         if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data))
  178.                 return -1;
  179.         else
  180.                 return 0x0FF & data.byte;
  181. }
  182.  
  183. static inline __s32 i2c_smbus_write_byte(int file, __u8 value)
  184. {
  185.         return i2c_smbus_access(file,I2C_SMBUS_WRITE,value,
  186.                                 I2C_SMBUS_BYTE,NULL);
  187. }
  188.  
  189. static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)
  190. {
  191.         union i2c_smbus_data data;
  192.         if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
  193.                              I2C_SMBUS_BYTE_DATA,&data))
  194.                 return -1;
  195.         else
  196.                 return 0x0FF & data.byte;
  197. }
  198.  
  199. static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command,
  200.                                               __u8 value)
  201. {
  202.         union i2c_smbus_data data;
  203.         data.byte = value;
  204.         return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
  205.                                 I2C_SMBUS_BYTE_DATA, &data);
  206. }
  207.  
  208. static inline __s32 i2c_smbus_read_word_data(int file, __u8 command)
  209. {
  210.         union i2c_smbus_data data;
  211.         if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
  212.                              I2C_SMBUS_WORD_DATA,&data))
  213.                 return -1;
  214.         else
  215.                 return 0x0FFFF & data.word;
  216. }
  217.  
  218. static inline __s32 i2c_smbus_write_word_data(int file, __u8 command,
  219.                                               __u16 value)
  220. {
  221.         union i2c_smbus_data data;
  222.         data.word = value;
  223.         return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
  224.                                 I2C_SMBUS_WORD_DATA, &data);
  225. }
  226.  
  227. static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
  228. {
  229.         union i2c_smbus_data data;
  230.         data.word = value;
  231.         if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
  232.                              I2C_SMBUS_PROC_CALL,&data))
  233.                 return -1;
  234.         else
  235.                 return 0x0FFFF & data.word;
  236. }
  237.  
  238.  
  239. /* Returns the number of read bytes */
  240. static inline __s32 i2c_smbus_read_block_data(int file, __u8 command,
  241.                                               __u8 *values)
  242. {
  243.         union i2c_smbus_data data;
  244.         int i;
  245.         if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
  246.                              I2C_SMBUS_BLOCK_DATA,&data))
  247.                 return -1;
  248.         else {
  249.                 for (i = 1; i <= data.block[0]; i++)
  250.                         values[i-1] = data.block[i];
  251.                 return data.block[0];
  252.         }
  253. }
  254.  
  255. static inline __s32 i2c_smbus_write_block_data(int file, __u8 command,
  256.                                                __u8 length, const __u8 *values)
  257. {
  258.         union i2c_smbus_data data;
  259.         int i;
  260.         if (length > 32)
  261.                 length = 32;
  262.         for (i = 1; i <= length; i++)
  263.                 data.block[i] = values[i-1];
  264.         data.block[0] = length;
  265.         return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
  266.                                 I2C_SMBUS_BLOCK_DATA, &data);
  267. }
  268.  
  269. /* Returns the number of read bytes */
  270. /* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
  271.    ask for less than 32 bytes, your code will only work with kernels
  272.    2.6.23 and later. */
  273. static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,
  274.                                                   __u8 length, __u8 *values)
  275. {
  276.         union i2c_smbus_data data;
  277.         int i;
  278.  
  279.         if (length > 32)
  280.                 length = 32;
  281.         data.block[0] = length;
  282.         if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
  283.                              length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
  284.                               I2C_SMBUS_I2C_BLOCK_DATA,&data))
  285.                 return -1;
  286.         else {
  287.                 for (i = 1; i <= data.block[0]; i++)
  288.                         values[i-1] = data.block[i];
  289.                 return data.block[0];
  290.         }
  291. }
  292.  
  293. static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,
  294.                                                    __u8 length,
  295.                                                    const __u8 *values)
  296. {
  297.         union i2c_smbus_data data;
  298.         int i;
  299.         if (length > 32)
  300.                 length = 32;
  301.         for (i = 1; i <= length; i++)
  302.                 data.block[i] = values[i-1];
  303.         data.block[0] = length;
  304.         return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
  305.                                 I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
  306. }
  307.  
  308. /* Returns the number of read bytes */
  309. static inline __s32 i2c_smbus_block_process_call(int file, __u8 command,
  310.                                                  __u8 length, __u8 *values)
  311. {
  312.         union i2c_smbus_data data;
  313.         int i;
  314.         if (length > 32)
  315.                 length = 32;
  316.         for (i = 1; i <= length; i++)
  317.                 data.block[i] = values[i-1];
  318.         data.block[0] = length;
  319.         if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
  320.                              I2C_SMBUS_BLOCK_PROC_CALL,&data))
  321.                 return -1;
  322.         else {
  323.                 for (i = 1; i <= data.block[0]; i++)
  324.                         values[i-1] = data.block[i];
  325.                 return data.block[0];
  326.         }
  327. }
  328.  
  329.  
  330. #endif /* _LINUX_I2C_DEV_H */
  331.  


 
« Last Edit: April 06, 2019, 03:28:59 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 2622
    • ScriptBasic Open Source Project
Re: SB π
« Reply #136 on: April 05, 2019, 07:02:47 PM »
Here is the humidity.c example from the Sense HAT C link AIR provided. Creating an extension module for the low level functions should allow the rest to be done in ScriptBasic.

Code: C
  1. /*
  2.  *  C code to read humidity and temperature from the
  3.  *  Raspberry Pi Sense HAT add-on board (HTS221 sensor)
  4.  *
  5.  *  sudo raspi-config --> advanced options --> enable i2c
  6.  *
  7.  *  sudo apt-get install libi2c-dev i2c-tools
  8.  *
  9.  *  Then build with:
  10.  *
  11.  *       gcc -Wall humidity.c -o humidity
  12.  *
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <stdint.h>
  17. #include <unistd.h>
  18. #include <stdlib.h>
  19. #include <fcntl.h>
  20. #include <linux/i2c-dev.h>
  21.  
  22. #define DEV_PATH "/dev/i2c-1"
  23. #define DEV_ID 0x5F
  24. #define WHO_AM_I 0x0F
  25.  
  26. #define CTRL_REG1 0x20
  27. #define CTRL_REG2 0x21
  28.  
  29. #define T0_OUT_L 0x3C
  30. #define T0_OUT_H 0x3D
  31. #define T1_OUT_L 0x3E
  32. #define T1_OUT_H 0x3F
  33. #define T0_degC_x8 0x32
  34. #define T1_degC_x8 0x33
  35. #define T1_T0_MSB 0x35
  36.  
  37. #define TEMP_OUT_L 0x2A
  38. #define TEMP_OUT_H 0x2B
  39.  
  40. #define H0_T0_OUT_L 0x36
  41. #define H0_T0_OUT_H 0x37
  42. #define H1_T0_OUT_L 0x3A
  43. #define H1_T0_OUT_H 0x3B
  44. #define H0_rH_x2 0x30
  45. #define H1_rH_x2 0x31
  46.  
  47. #define H_T_OUT_L 0x28
  48. #define H_T_OUT_H 0x29
  49.  
  50. void delay(int);
  51.  
  52. int main(void)
  53. {
  54.     int fd = 0;
  55.     uint8_t status = 0;
  56.  
  57.     /* open i2c comms */
  58.     if ((fd = open(DEV_PATH, O_RDWR)) < 0) {
  59.         perror("Unable to open i2c device");
  60.         exit(1);
  61.     }
  62.  
  63.     /* configure i2c slave */
  64.     if (ioctl(fd, I2C_SLAVE, DEV_ID) < 0) {
  65.         perror("Unable to configure i2c slave device");
  66.         close(fd);
  67.         exit(1);
  68.     }
  69.  
  70.     /* check we are who we should be */
  71.     if (i2c_smbus_read_byte_data(fd, WHO_AM_I) != 0xBC) {
  72.         printf("%s\n", "who_am_i error");
  73.         close(fd);
  74.         exit(1);
  75.     }
  76.  
  77.     /* Power down the device (clean start) */
  78.     i2c_smbus_write_byte_data(fd, CTRL_REG1, 0x00);
  79.  
  80.     /* Turn on the humidity sensor analog front end in single shot mode  */
  81.     i2c_smbus_write_byte_data(fd, CTRL_REG1, 0x84);
  82.  
  83.     /* Run one-shot measurement (temperature and humidity). The set bit will be reset by the
  84.      * sensor itself after execution (self-clearing bit) */
  85.     i2c_smbus_write_byte_data(fd, CTRL_REG2, 0x01);
  86.  
  87.     /* Wait until the measurement is completed */
  88.     do {
  89.         delay(25);              /* 25 milliseconds */
  90.         status = i2c_smbus_read_byte_data(fd, CTRL_REG2);
  91.     }
  92.     while (status != 0);
  93.  
  94.     /* Read calibration temperature LSB (ADC) data
  95.      * (temperature calibration x-data for two points)
  96.      */
  97.     uint8_t t0_out_l = i2c_smbus_read_byte_data(fd, T0_OUT_L);
  98.     uint8_t t0_out_h = i2c_smbus_read_byte_data(fd, T0_OUT_H);
  99.     uint8_t t1_out_l = i2c_smbus_read_byte_data(fd, T1_OUT_L);
  100.     uint8_t t1_out_h = i2c_smbus_read_byte_data(fd, T1_OUT_H);
  101.  
  102.     /* Read calibration temperature (C) data
  103.      * (temperature calibration y-data for two points)
  104.      */
  105.     uint8_t t0_degC_x8 = i2c_smbus_read_byte_data(fd, T0_degC_x8);
  106.     uint8_t t1_degC_x8 = i2c_smbus_read_byte_data(fd, T1_degC_x8);
  107.     uint8_t t1_t0_msb = i2c_smbus_read_byte_data(fd, T1_T0_MSB);
  108.  
  109.     /* Read calibration relative humidity LSB (ADC) data
  110.      * (humidity calibration x-data for two points)
  111.      */
  112.     uint8_t h0_out_l = i2c_smbus_read_byte_data(fd, H0_T0_OUT_L);
  113.     uint8_t h0_out_h = i2c_smbus_read_byte_data(fd, H0_T0_OUT_H);
  114.     uint8_t h1_out_l = i2c_smbus_read_byte_data(fd, H1_T0_OUT_L);
  115.     uint8_t h1_out_h = i2c_smbus_read_byte_data(fd, H1_T0_OUT_H);
  116.  
  117.     /* Read relative humidity (% rH) data
  118.      * (humidity calibration y-data for two points)
  119.      */
  120.     uint8_t h0_rh_x2 = i2c_smbus_read_byte_data(fd, H0_rH_x2);
  121.     uint8_t h1_rh_x2 = i2c_smbus_read_byte_data(fd, H1_rH_x2);
  122.  
  123.     /* make 16 bit values (bit shift)
  124.      * (temperature calibration x-values)
  125.      */
  126.     int16_t T0_OUT = t0_out_h << 8 | t0_out_l;
  127.     int16_t T1_OUT = t1_out_h << 8 | t1_out_l;
  128.  
  129.     /* make 16 bit values (bit shift)
  130.      * (humidity calibration x-values)
  131.      */
  132.     int16_t H0_T0_OUT = h0_out_h << 8 | h0_out_l;
  133.     int16_t H1_T0_OUT = h1_out_h << 8 | h1_out_l;
  134.  
  135.     /* make 16 and 10 bit values (bit mask and bit shift) */
  136.     uint16_t T0_DegC_x8 = (t1_t0_msb & 3) << 8 | t0_degC_x8;
  137.     uint16_t T1_DegC_x8 = ((t1_t0_msb & 12) >> 2) << 8 | t1_degC_x8;
  138.  
  139.     /* Calculate calibration values
  140.      * (temperature calibration y-values)
  141.      */
  142.     double T0_DegC = T0_DegC_x8 / 8.0;
  143.     double T1_DegC = T1_DegC_x8 / 8.0;
  144.  
  145.     /* Humidity calibration values
  146.      * (humidity calibration y-values)
  147.      */
  148.     double H0_rH = h0_rh_x2 / 2.0;
  149.     double H1_rH = h1_rh_x2 / 2.0;
  150.  
  151.     /* Solve the linear equasions 'y = mx + c' to give the
  152.      * calibration straight line graphs for temperature and humidity
  153.      */
  154.     double t_gradient_m = (T1_DegC - T0_DegC) / (T1_OUT - T0_OUT);
  155.     double t_intercept_c = T1_DegC - (t_gradient_m * T1_OUT);
  156.  
  157.     double h_gradient_m = (H1_rH - H0_rH) / (H1_T0_OUT - H0_T0_OUT);
  158.     double h_intercept_c = H1_rH - (h_gradient_m * H1_T0_OUT);
  159.  
  160.     /* Read the ambient temperature measurement (2 bytes to read) */
  161.     uint8_t t_out_l = i2c_smbus_read_byte_data(fd, TEMP_OUT_L);
  162.     uint8_t t_out_h = i2c_smbus_read_byte_data(fd, TEMP_OUT_H);
  163.  
  164.     /* make 16 bit value */
  165.     int16_t T_OUT = t_out_h << 8 | t_out_l;
  166.  
  167.     /* Read the ambient humidity measurement (2 bytes to read) */
  168.     uint8_t h_t_out_l = i2c_smbus_read_byte_data(fd, H_T_OUT_L);
  169.     uint8_t h_t_out_h = i2c_smbus_read_byte_data(fd, H_T_OUT_H);
  170.  
  171.     /* make 16 bit value */
  172.     int16_t H_T_OUT = h_t_out_h << 8 | h_t_out_l;
  173.  
  174.     /* Calculate ambient temperature */
  175.     double T_DegC = (t_gradient_m * T_OUT) + t_intercept_c;
  176.  
  177.     /* Calculate ambient humidity */
  178.     double H_rH = (h_gradient_m * H_T_OUT) + h_intercept_c;
  179.  
  180.     /* Output */
  181.     printf("Temp (from humid) = %.1fC\n", T_DegC);
  182.     printf("Humidity = %.0f%% rH\n", H_rH);
  183.  
  184.     /* Power down the device */
  185.     i2c_smbus_write_byte_data(fd, CTRL_REG1, 0x00);
  186.     close(fd);
  187.  
  188.     return (0);
  189. }
  190.  
  191. void delay(int t)
  192. {
  193.     usleep(t * 1000);
  194. }
  195.  


pi@raspberrypi:~/sbrpi/sensehat $ ./humidity
Temp (from humid) = 29.5C
Humidity = 40% rH
pi@raspberrypi:~/sbrpi/sensehat $

« Last Edit: April 06, 2019, 03:28:42 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 2622
    • ScriptBasic Open Source Project
Re: SB π
« Reply #137 on: April 05, 2019, 07:07:47 PM »
Here is the pressure.c example.

Code: C
  1. /*
  2.  *  C code to read pressure and temperature from the
  3.  *  Raspberry Pi Sense HAT add-on board (LPS25H sensor)
  4.  *  
  5.  *  sudo raspi-config --> advanced options --> enable i2c
  6.  *
  7.  *  sudo apt-get install libi2c-dev i2c-tools
  8.  *
  9.  *  Then build with:
  10.  *
  11.  *       gcc -Wall pressure.c -o pressure
  12.  *
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <stdint.h>
  17. #include <unistd.h>
  18. #include <linux/i2c-dev.h>
  19. #include <stdlib.h>
  20. #include <fcntl.h>
  21.  
  22. #define DEV_ID 0x5c
  23. #define DEV_PATH "/dev/i2c-1"
  24. #define WHO_AM_I 0x0F
  25. #define CTRL_REG1 0x20
  26. #define CTRL_REG2 0x21
  27. #define PRESS_OUT_XL 0x28
  28. #define PRESS_OUT_L 0x29
  29. #define PRESS_OUT_H 0x2A
  30. #define TEMP_OUT_L 0x2B
  31. #define TEMP_OUT_H 0x2C
  32.  
  33. void delay(int);
  34.  
  35. int main(void)
  36. {
  37.     int fd = 0;
  38.     uint8_t temp_out_l = 0, temp_out_h = 0;
  39.     int16_t temp_out = 0;
  40.     double t_c = 0.0;
  41.  
  42.     uint8_t press_out_xl = 0;
  43.     uint8_t press_out_l = 0;
  44.     uint8_t press_out_h = 0;
  45.  
  46.     int32_t press_out = 0;
  47.     double pressure = 0.0;
  48.  
  49.     uint8_t status = 0;
  50.  
  51.     /* open i2c comms */
  52.     if ((fd = open(DEV_PATH, O_RDWR)) < 0) {
  53.         perror("Unable to open i2c device");
  54.         exit(1);
  55.     }
  56.  
  57.     /* configure i2c slave */
  58.     if (ioctl(fd, I2C_SLAVE, DEV_ID) < 0) {
  59.         perror("Unable to configure i2c slave device");
  60.         close(fd);
  61.         exit(1);
  62.     }
  63.  
  64.     /* check we are who we should be */
  65.     if (i2c_smbus_read_byte_data(fd, WHO_AM_I) != 0xBD) {
  66.         printf("%s\n", "who_am_i error");
  67.         close(fd);
  68.         exit(1);
  69.     }
  70.  
  71.     /* Power down the device (clean start) */
  72.     i2c_smbus_write_byte_data(fd, CTRL_REG1, 0x00);
  73.  
  74.     /* Turn on the pressure sensor analog front end in single shot mode  */
  75.     i2c_smbus_write_byte_data(fd, CTRL_REG1, 0x84);
  76.  
  77.     /* Run one-shot measurement (temperature and pressure), the set bit will be reset by the
  78.      * sensor itself after execution (self-clearing bit) */
  79.     i2c_smbus_write_byte_data(fd, CTRL_REG2, 0x01);
  80.  
  81.     /* Wait until the measurement is complete */
  82.     do {
  83.         delay(25);              /* 25 milliseconds */
  84.         status = i2c_smbus_read_byte_data(fd, CTRL_REG2);
  85.     }
  86.     while (status != 0);
  87.  
  88.     /* Read the temperature measurement (2 bytes to read) */
  89.     temp_out_l = i2c_smbus_read_byte_data(fd, TEMP_OUT_L);
  90.     temp_out_h = i2c_smbus_read_byte_data(fd, TEMP_OUT_H);
  91.  
  92.     /* Read the pressure measurement (3 bytes to read) */
  93.     press_out_xl = i2c_smbus_read_byte_data(fd, PRESS_OUT_XL);
  94.     press_out_l = i2c_smbus_read_byte_data(fd, PRESS_OUT_L);
  95.     press_out_h = i2c_smbus_read_byte_data(fd, PRESS_OUT_H);
  96.  
  97.     /* make 16 and 24 bit values (using bit shift) */
  98.     temp_out = temp_out_h << 8 | temp_out_l;
  99.     press_out = press_out_h << 16 | press_out_l << 8 | press_out_xl;
  100.  
  101.     /* calculate output values */
  102.     t_c = 42.5 + (temp_out / 480.0);
  103.     pressure = press_out / 4096.0;
  104.  
  105.     /*output */
  106.     printf("Temp (from press) = %.2fC\n", t_c);
  107.     printf("Pressure = %.0f hPa\n", pressure);
  108.  
  109.     /* Power down the device */
  110.     i2c_smbus_write_byte_data(fd, CTRL_REG1, 0x00);
  111.  
  112.     close(fd);
  113.  
  114.     return (0);
  115. }
  116.  
  117. void delay(int t)
  118. {
  119.     usleep(t * 1000);
  120. }
  121.  


pi@raspberrypi:~/sbrpi/sensehat $ ./pressure
Temp (from press) = 32.06C
Pressure = 1009 hPa
pi@raspberrypi:~/sbrpi/sensehat $


« Last Edit: April 06, 2019, 03:28:25 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 2622
    • ScriptBasic Open Source Project
Re: SB π
« Reply #138 on: April 05, 2019, 07:28:28 PM »
The led_matrix.c program works as well.

Code: C
  1. /*
  2.  *  C code to demonstrate control of the LED matrix for the
  3.  *  Raspberry Pi Sense HAT add-on board.
  4.  *
  5.  *  Uses the mmap method to map the led device into memory
  6.  *
  7.  *  Build with:
  8.  *
  9.  *       gcc -Wall led_matrix.c -o led_matrix
  10.  *
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include <unistd.h>
  18. #include <fcntl.h>
  19. #include <sys/mman.h>
  20. #include <stdint.h>
  21. #include <string.h>
  22. #include <linux/fb.h>
  23. #include <sys/ioctl.h>
  24.  
  25. #define FILEPATH "/dev/fb1"
  26. #define NUM_WORDS 64
  27. #define FILESIZE (NUM_WORDS * sizeof(uint16_t))
  28.  
  29. #define RGB565_RED 0xF800
  30.  
  31. void delay(int);
  32.  
  33. int main(void)
  34. {
  35.     int i;
  36.     int fbfd;
  37.     uint16_t *map;
  38.     uint16_t *p;
  39.     struct fb_fix_screeninfo fix_info;
  40.  
  41.     /* open the led frame buffer device */
  42.     fbfd = open(FILEPATH, O_RDWR);
  43.     if (fbfd == -1) {
  44.         perror("Error (call to 'open')");
  45.         exit(EXIT_FAILURE);
  46.     }
  47.  
  48.     /* read fixed screen info for the open device */
  49.     if (ioctl(fbfd, FBIOGET_FSCREENINFO, &fix_info) == -1) {
  50.         perror("Error (call to 'ioctl')");
  51.         close(fbfd);
  52.         exit(EXIT_FAILURE);
  53.     }
  54.  
  55.     /* now check the correct device has been found */
  56.     if (strcmp(fix_info.id, "RPi-Sense FB") != 0) {
  57.         printf("%s\n", "Error: RPi-Sense FB not found");
  58.         close(fbfd);
  59.         exit(EXIT_FAILURE);
  60.     }
  61.  
  62.     /* map the led frame buffer device into memory */
  63.     map =
  64.         mmap(NULL, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
  65.     if (map == MAP_FAILED) {
  66.         close(fbfd);
  67.         perror("Error mmapping the file");
  68.         exit(EXIT_FAILURE);
  69.     }
  70.  
  71.     /* set a pointer to the start of the memory area */
  72.     p = map;
  73.  
  74.     /* clear the led matrix */
  75.     memset(map, 0, FILESIZE);
  76.  
  77.     /* light it up! */
  78.     for (i = 0; i < NUM_WORDS; i++) {
  79.         *(p + i) = RGB565_RED;
  80.         delay(25);
  81.     }
  82.  
  83.     /* flash white */
  84.     for (i = 0; i < 3; i++) {
  85.         delay(250);
  86.         memset(map, 0xFF, FILESIZE);
  87.         delay(250);
  88.         memset(map, 0, FILESIZE);
  89.     }
  90.     delay(250);
  91.  
  92.     /* clear the led matrix */
  93.     memset(map, 0, FILESIZE);
  94.  
  95.     /* un-map and close */
  96.     if (munmap(map, FILESIZE) == -1) {
  97.         perror("Error un-mmapping the file");
  98.     }
  99.     close(fbfd);
  100.  
  101.     return 0;
  102. }
  103.  
  104. void delay(int t)
  105. {
  106.     usleep(t * 1000);
  107. }
  108.  

« Last Edit: April 06, 2019, 03:27:21 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 2622
    • ScriptBasic Open Source Project
Re: SB π
« Reply #139 on: April 06, 2019, 04:32:59 PM »
I was able to format a 128 GB USB stick as a Linux file system and compile SB on it.


Compilation: Apr  6 2019 16:28:41
mkdir: cannot create directory /media/pi/usb_drive/sb-dev-cleanup/bin/var/httpd: File exists
ar: creating /media/pi/usb_drive/sb-dev-cleanup/bin/lib/libscriba.a
scriba executable OK 
sbhttpd executable OK 
libscriba library OK 
MODULE slre:     dll OK   lib OK   bas OK 
MODULE sdbg:     dll OK   lib OK   bas OK 
MODULE hash:     dll OK   lib OK   bas OK 
MODULE zlib:     dll OK   lib OK   bas OK 
MODULE odbc:     dll OK   lib OK   bas OK 
MODULE mysql:    dll OK   lib OK   bas OK 
MODULE curl:     dll OK   lib OK   bas OK 
MODULE trial:    dll OK   lib OK   bas OK 
MODULE mxml:     dll OK   lib OK   bas OK 
MODULE curses:   dll OK   lib OK   bas OK 
MODULE t:        dll OK   lib OK   bas OK 
MODULE ux:       dll OK   lib OK   bas OK 
MODULE sbt:      dll OK   lib OK   bas OK 
MODULE json:     dll OK   lib OK   bas OK 
MODULE dbg:      dll OK   lib OK   bas OK 
MODULE sqlite:   dll OK   lib OK   bas OK 
MODULE mt:       dll OK   lib OK   bas OK 
MODULE cgi:      dll OK   lib OK   bas OK 
MODULE ip:       dll OK   lib OK   bas OK 
pi@raspberrypi:/media/pi/usb_drive/sb-dev-cleanup $


Offline John

  • Forum Support / SB Dev
  • Posts: 2622
    • ScriptBasic Open Source Project
Re: SB π
« Reply #140 on: April 06, 2019, 05:19:22 PM »
AIR,

I feel the new AppImage with the dependencies included is working well on the RPi. Can you push the new make script so it becomes the default?

Offline AIR

  • BASIC Developer
  • Posts: 628
Re: SB Pi
« Reply #141 on: April 06, 2019, 11:40:21 PM »
There is no script for the included external libs, I did that manually.

BTW, to eliminate the requirement that the esd.pm module be installed (which requires root), edit setup.pl.

After the #!/usr/bin/perl add the following:
Code: [Select]
use Cwd qw(cwd);
Then at line 177 change:
Code: [Select]
$esdlocation = undef;to
Code: [Select]
$esdlocation = cwd;
This tells the setup.pl file to use the esd.pm that is in the current (sb-dev if using the source from git) folder.

AIR.

Offline John

  • Forum Support / SB Dev
  • Posts: 2622
    • ScriptBasic Open Source Project
Re: SB π
« Reply #142 on: April 07, 2019, 01:41:28 PM »
Thanks AIR!

That should stop the noise on the Raspberry Pi forum about having to use root / sudo to build ScriptBasic.

Offline John

  • Forum Support / SB Dev
  • Posts: 2622
    • ScriptBasic Open Source Project
Re: SB π
« Reply #143 on: April 07, 2019, 02:57:29 PM »
Quote from: ejolson@RPi Forum
I now have ScriptBasic running on a Raspberry Pi Zero W.

That is a $5 computer.  8)


Offline John

  • Forum Support / SB Dev
  • Posts: 2622
    • ScriptBasic Open Source Project
Re: SB π
« Reply #144 on: April 07, 2019, 06:04:24 PM »

pi@raspberrypi:~ $ pwd
/home/pi
pi@raspberrypi:~ $ ls -l usb
lrwxrwxrwx 1 root root 19 Apr  7 17:57 usb -> /media/pi/usb_drive
pi@raspberrypi:~ $


Like adding another 128 GB of storage to my home directory.


Offline John

  • Forum Support / SB Dev
  • Posts: 2622
    • ScriptBasic Open Source Project
Re: SB π
« Reply #145 on: April 07, 2019, 08:10:20 PM »
Quote from: ejolson@RPi Forum
Quote from: me
The question is can someone viewing the program execution results (not using time) tell you which seems faster?

There are plenty of interpreters slower than ScriptBasic that are in widespread use. The exact same recursive Fibonacci code written in bash looks like

Code: Bash
  1. #!/bin/bash
  2. fibo_work(){
  3.     case $1 in
  4. 1|2)    let y=1;;
  5. *)      let x=$1-1; fibo_work $x; local fa=$y
  6.         let x=$1-2; fibo_work $x; local fb=$y
  7.         let y=$fa+$fb;;
  8.     esac
  9. }
  10. fibo_work 24
  11. echo $y
  12.  

and on the Pi Zero obtains a execution speed of


$ time ./fibo.sh
46368

 real 1m5.533s
 user 1m4.509s
 sys 0m0.020s


which is more than 30 times slower than ScriptBasic.

 :)
« Last Edit: April 07, 2019, 09:19:44 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 2622
    • ScriptBasic Open Source Project
Re: SB π
« Reply #146 on: April 08, 2019, 12:24:20 PM »
I just ordered a Raspberry Pi Zero which should arrive tomorrow. I'll get a ScriptBasic build for it posted soon.

I'm looking forward to compare the performance between the Raspberry  Pi Zero and the 3 B.

« Last Edit: April 08, 2019, 02:30:06 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 2622
    • ScriptBasic Open Source Project
Re: SB π
« Reply #147 on: April 08, 2019, 02:33:38 PM »
AIR,

Can you post the steps to include the dependencies in the AppImage or is it too complex to make public?

Offline AIR

  • BASIC Developer
  • Posts: 628
Re: SB π
« Reply #148 on: April 08, 2019, 04:27:07 PM »
Download: https://github.com/probonopd/AppImages/files/794641/curl-7.53.0-wheezy.zip
Download: https://curl.haxx.se/download/curl-7.64.1.tar.gz

Unpack both

Copy the "debian" folder from the curl-7.53.0-wheezy folder into the source tree for curl-7.64

Execute:  dpkg-buildpackage -rfakeroot -b -us -uc while in the curl-7.64 folder.  You may need to install the fakeroot and debhelper packages.

Extract the sb.AppImage file.

Copy the contents of curl-7.64.1/debian/libcurl3/usr/lib to the usr/lib folder in the extracted appimage
Copy /usr/lib/arm-linux-gnueabihf/libmariadbclient.so.18.0.0 to the /usr/lib folder in the extracted appimage
Copy /usr/lib/arm-linux-gnueabihf/libsqlite3.so.0 to the usr/lib folder in the extracted appimage
Copy /usr/lib/arm-linux-gnueabihf/libiodbc.so.2.1.20 and /usr/lib/arm-linux-gnueabihf/libiodbcinst.so.2.1.20 to the usr/lib folder in the extracted appimage

Edit the AppRun file in the extracted appimage folder, and add a new line with: export LD_LIBRARY_PATH="${WORKDIR}/usr/lib" before the "TEXT_CONF=$(mktemp)" line.  If it's already there, skip this part.

Run appimagetool passing the extracted appimage folder as the parameter to generate the final appimage.


AIR.

« Last Edit: April 08, 2019, 04:31:34 PM by AIR »

Offline AIR

  • BASIC Developer
  • Posts: 628
Re: SB π
« Reply #149 on: April 08, 2019, 04:38:20 PM »
BTW, I update the setup.pl file in the "cleanup" branch so it no longer requires installing esd.pm into the system perl path.  It now use the local copy of esd.pm"