Showing posts with label Texas Instrument. Show all posts
Showing posts with label Texas Instrument. Show all posts

Friday, September 1, 2023

Using Z-Wave Multilevel sensor example running on BRD2603A/ZGM230S to read temperature from TMP116 temperature sensor

The following example shows you how to use Z-Wave Multilevel sensor example running on BRD2603A/ZGM230S to read temperature from Texas Instrument TMP116 temperature sensor.

1. Connect Texas Instrument BOOSTXL-BASSENSORS TMP116 TMP V+, GND, and SCL/SDA to pin 20, 1, and 15(PB05)/16(PB05) on EXP-header of BRD2603A.

 

2. Install Z-Wave Debug and Z-Wave Debug Print in project software component to use  DEBUGPRINT to output data to SSv5 console 1.

3.Add the following code into MultilevelSensor_interface_sensor.c

 #define TMP116_I2C_DEVICE                (sl_i2cspm_sensor) /**< I2C device used to control the Si7021  */
#define TMP116_I2C_BUS_ADDRESS           0x48//TMP116 0x40               /**< I2C bus address                        */

static I2C_TransferReturn_TypeDef TMP116_transaction(uint16_t flag,
                                                     uint8_t *writeCmd,
                                                     size_t writeLen,
                                                     uint8_t *readCmd,
                                                     size_t readLen)
{
  I2C_TransferSeq_TypeDef seq;
  I2C_TransferReturn_TypeDef ret;

  seq.addr = TMP116_I2C_BUS_ADDRESS << 1;
  seq.flags = flag;

  switch (flag) {
    // Send the write command from writeCmd
    case I2C_FLAG_WRITE:
      seq.buf[0].data = writeCmd;
      seq.buf[0].len  = writeLen;

      break;

    // Receive data into readCmd of readLen
    case I2C_FLAG_READ:
      seq.buf[0].data = readCmd;
      seq.buf[0].len  = readLen;

      break;

    // Send the write command from writeCmd
    // and receive data into readCmd of readLen
    case I2C_FLAG_WRITE_READ:
      seq.buf[0].data = writeCmd;
      seq.buf[0].len  = writeLen;

      seq.buf[1].data = readCmd;
      seq.buf[1].len  = readLen;

      break;

    default:
      return i2cTransferUsageFault;
  }

  // Perform the transfer and return status from the transfer
  ret = I2CSPM_Transfer(TMP116_I2C_DEVICE, &seq);

  return ret;
}

uint32_t TMP116_read()
{
  I2C_TransferReturn_TypeDef ret;
  uint8_t temp[2];
  uint8_t cmdReadTemp[1]={0x00};
  int32_t temperature;

  // Wait for sensor to become ready
  //sl_sleeptimer_delay_millisecond(1000);

  // Check for device presence  and compare device ID
  ret = TMP116_transaction(I2C_FLAG_WRITE_READ, cmdReadTemp, 1, temp, 2);
  temperature=temp[0];
  temperature=(temperature<<8)|temp[1];
  //DPRINTF("Temperature = %d\r\n", (int)temperature);
  return temperature*10;
}

4. Replace "MultilevelSensor_temperature_humidity_sensor_read(&rh_data, &temp_data);" with "temp_data=(int32_t)TMP116_read();" in cc_multilevel_sensor_air_temperature_interface_read_value.

5. Build and run the firmware on BRD2603A to see the following temperature reading fromTMP116

 


P.S. If you use Texas Instrument instead of TMP117, it should work similarly. 

 

Thursday, August 31, 2023

Using Z-Wave Multilevel sensor example running on BRD2603A/ZGM230S to read temperature from DS18B20 one-wire sensor

The following example shows you how to use Z-Wave 800 Multilevel sensor example running on BRD2603A/ZGM230S to read temperature from DS18B20 one-wire sensor.

1. Connect DS18B20 Vdd, GND, and DQ (add extra 4.7K pull-high to Vdd) to pin 20, 1, and 2(PB03) on EXP-header of BRD2603A.

2. Install USTIMER, Z-Wave Debug, and Z-Wave Debug Print in project software component to use microsecond delay API USTIMER_DelayIntSafe and DEBUGPRINT to output data to SSv5 console 1.

3. Add the following code into MultilevelSensor_interface_sensor.c

#include "em_gpio.h"
#include "ustimer.h" //For microsecond delay
#include "em_core_generic.h" //For critical section

//Use PB03 on BRD2603A
#define DS_GPIO_PORT 1 //gpioPortB
#define DS_GPIO_PIN  3

#define CMD_CONVERTTEMP 0x44
#define CMD_RSCRATCHPAD 0xbe
#define CMD_WSCRATCHPAD 0x4e
#define CMD_CPYSCRATCHPAD 0x48
#define CMD_RECEEPROM 0xb8
#define CMD_RPWRSUPPLY 0xb4
#define CMD_SEARCHROM 0xf0
#define CMD_READROM 0x33
#define CMD_MATCHROM 0x55
#define CMD_SKIPROM 0xcc
#define CMD_ALARMSEARCH 0xec
#define DECIMAL_STEPS_12BIT 625 //.0625

inline void pullLineLow() {
    GPIO_PinModeSet(DS_GPIO_PORT, DS_GPIO_PIN, gpioModePushPull, 0);
}

inline void releaseLine() {
    GPIO_PinModeSet(DS_GPIO_PORT, DS_GPIO_PIN, gpioModeInputPull, 1);
}

inline void delayUs(uint16_t us) {
  USTIMER_DelayIntSafe(us);
}

inline uint32_t readLineState() {
    return GPIO_PinInGet(DS_GPIO_PORT, DS_GPIO_PIN);
}

void writeBit(uint8_t bit){
  //Pull line low for 1uS
  pullLineLow();
  delayUs(1);
  //If we want to write 1, release the line (if not will keep low)
  if(bit) {
        releaseLine();
    }
  //Wait for a while and release the line
  delayUs(20);
  releaseLine();
  delayUs(1);
}

uint8_t readBit(void){
  uint8_t bit = 0;
  //Pull line low for 1uS
  pullLineLow();
  delayUs(1);
  //Release line and wait for a while
  releaseLine();
  delayUs(8);
  //Read line value
  if(readLineState()){
        bit=1;
    }
  //Wait for a while to return read value
  delayUs(40);
  return bit;
}

uint8_t readByte(void){
  uint8_t i = 8, n = 0;
  while(i--){
    //Shift one position right and store read value
    n >>= 1;
    n |= (readBit() << 7);
  }
  return n;
}

void writeByte(uint8_t b){
  uint8_t i = 8;
  while(i--){
    //Write actual bit and shift one position right to make the next bit ready
    writeBit(b & 1);
    b >>= 1;
  }
}

uint32_t reset(){
  uint32_t i;
  pullLineLow();
  delayUs(300);
  releaseLine();
  delayUs(60);
  i = readLineState(); //(0=OK, 1=ERROR)
  delayUs(300);
  return i;
}

/*
    Returns temperature read from DS18B20
    Reading is returned mutiplied by 10000 i.e.
    for 23.4560 degrees the result will be 234560
*/
uint32_t ds18b20GetTemparature(){
  USTIMER_Init();

  //Enter cirtical section
  CORE_DECLARE_IRQ_STATE;
  CORE_ENTER_CRITICAL();

  //Reset, skip ROM and start temperature conversion
  if(reset()) {
      DPRINT("DS18B20 is not responding---reset temperature conversion\n");
        return 0;
    }
  writeByte(CMD_SKIPROM);
  writeByte(CMD_CONVERTTEMP);

  //Wait until conversion is complete
  uint16_t timeout = 0xFFFF;
  while(!readBit() && timeout > 0) {
        timeout--;
        //Feed WDG to avoid WDG reboot.
        zpal_feed_watchdog();
    }
    if(0 == timeout) {
        DPRINT("DS18B20 temperature conversion has timed out\n");
        return 0;
    }

  //Reset, skip ROM and send command to read Scratchpad
  if(reset()) {
      DPRINT("DS18B20 is not responding---reset Scratchpad\n");
        return 0;
    }
  writeByte(CMD_SKIPROM);
  writeByte(CMD_RSCRATCHPAD);

  uint8_t scratchpad[2] = {0, 0};
  //Read Scratchpad (only 2 first bytes)
  scratchpad[0] = readByte();
  scratchpad[1] = readByte();

  //Exit critial section.
  CORE_EXIT_CRITICAL();

  USTIMER_DeInit();

  int8_t digit = scratchpad[0] >> 4;
  digit |= (scratchpad[1] & 0x7) << 4;
  //Store decimal digits
  uint16_t decimal = scratchpad[0] & 0xf;
  decimal *= DECIMAL_STEPS_12BIT;

    return digit * 10000 + decimal;
}

4. Use the following two lines to replace "MultilevelSensor_temperature_humidity_sensor_read(&rh_data, &temp_data);" in cc_multilevel_sensor_air_temperature_interface_read_value.

    temp_data=ds18b20GetTemparature();
    temp_data=(int32_t)(temp_data/10);

5. Build and run the firmware on BRD2603A to see the following temperature reading from DS18B20.