Happy St. Patrick's Day to the Element14 Community!
I was wondering if there was anything that I could do quickly with something that was green. The Pi Pico came to mind immediately, but serendipity won the day.
When I arrived home after my morning walk with the granddog, I found a Fedex package on my doorstep. It was an Omron Sensor Evaluation Board 2CIE-EV that I had won in an Omron giveaway contest. And it was also green
.
There are 3 different versions of this board, in Raspberry Pi, Arduino MKR, and Feather form factors. I had won the Feather version, 2JCIE-EV01-FT1 https://components.omron.com/sensor/evaluation-board/2jcie .
The board has 6 onboard sensors and connectors for other sensors. They even provide 4 cables to enable external connections.
The only Feather that I had handy to use was a HUZZAH ESP8266. I had been using it to test I2C sensors, so the only pins that I had soldered were 3.3V, GND, SDA, and SCL. So, it seemed appropriate to try one of the onboard I2C sensors.
Omron has a GitHub repo for this board https://github.com/omron-devhub/2jcieev01-arduino . I decided to try the program for the SHT30 Humidity and Temperature sensor.
Here's the sensor board mounted on the Feather:
And the output on the Serial Monitor
The GitHub code is written for an ESP32, so I had to change some of the GPIO assignments - but because I don't have those pins soldered, it didn't matter anyway. LED1 is an RGB LED and those pins would have just toggled the colors.
The code just for reference.
HuzzahESP8266_Omron_2JCIE_SHT30.ino
/*
* MIT License
* Copyright (c) 2019, 2018 - present OMRON Corporation
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/* includes */
#include "sht30.h"
#include <Wire.h>
/* defines */
#define SHT30_ADDR 0x44
#define SHT30_STATUSMASK 0xFC1F
#define GPIO_LED_R_PIN 14
#define GPIO_LED_G_PIN 12
#define GPIO_LED_B_PIN 13
#define conv16_u8_h(a) (uint8_t)(a >> 8)
#define conv16_u8_l(a) (uint8_t)(a & 0xFF)
#define conv8s_u16_be(b, n) \
(uint16_t)(((uint16_t)b[n] << 8) | (uint16_t)b[n + 1])
#define ap_halt(a) {Serial.println(a); while (1) {}}
/* I2C functions */
/** <!-- i2c_write_reg16 {{{1 --> I2C write function for byte transfer.
*/
bool i2c_write_reg16(uint8_t slave_addr, uint16_t register_addr,
uint8_t *write_buff, uint8_t len) {
Wire.beginTransmission(slave_addr);
Wire.write(conv16_u8_h(register_addr));
Wire.write(conv16_u8_l(register_addr));
if (len > 0) {
for (uint8_t i = 0; i < len; i++) {
Wire.write(write_buff[i]);
}
}
Wire.endTransmission();
return false;
}
/** <!-- i2c_read_reg16 {{{1 --> I2C read function for bytes transfer.
*/
bool i2c_read_reg16(uint8_t slave_addr, uint16_t register_addr,
uint8_t *read_buff, uint8_t len) {
i2c_write_reg16(slave_addr, register_addr, NULL, 0);
Wire.requestFrom(slave_addr, len);
if (Wire.available() != len) {
return true;
}
for (uint16_t i = 0; i < len; i++) {
read_buff[i] = Wire.read();
}
return false;
}
/** <!-- sht30_setup {{{1 --> setup a humidity sensor.
*/
void sht30_setup() {
sht30_reset();
sht30_startcheck();
sht30_measstart();
}
/** <!-- sht30_reset {{{1 --> issue software reset and wait for it.
*/
void sht30_reset(void) {
i2c_write_reg16(SHT30_ADDR, SHT30_SOFTRESET, NULL, 0);
delay(10);
}
/** <!-- sht30_startcheck {{{1 --> clear status and check start status.
*/
void sht30_startcheck(void) {
uint16_t stat = 0;
i2c_write_reg16(SHT30_ADDR, SHT30_CLEARSTATUS, NULL, 0); // clear status
delay(1);
int retry = 10;
do {
stat = sht30_readstatus(); // check status
delay(10);
} while (((stat & SHT30_STATUSMASK) != 0x0000) && (retry-- > 0));
if (((stat & SHT30_STATUSMASK) != 0x0000) || (retry == 0)) {
ap_halt("cannot detect SHT30 working.");
}
}
/** <!-- sht30_measstart {{{1 --> start measurement.
*/
void sht30_measstart(void) {
i2c_write_reg16(SHT30_ADDR, SHT30_MEAS_HIGHPRD, NULL, 0);
}
/** <!-- sht30_readstatus {{{1 -->
*/
uint16_t sht30_readstatus(void) {
bool result;
uint8_t readbuffer[3] = {0, 0, 0};
uint16_t stat = 0xFFFF;
result = i2c_read_reg16(SHT30_ADDR, SHT30_READSTATUS, readbuffer, 3);
if (!result) {
stat = conv8s_u16_be(readbuffer, 0);
}
return stat;
}
/** <!-- sht30_readTempHumi {{{1 --> read raw digits and
* convert them to physical values.
*/
int sht30_readTempHumi(int32_t* humi, int32_t* temp) {
bool result;
uint8_t readbuffer[6];
result = i2c_read_reg16(SHT30_ADDR, SHT30_READ_PERIODIC, readbuffer, 6);
if (result) {
return 1;
}
if (readbuffer[2] != sht30_crc8(readbuffer, 2)) {
return 2; // check crc8 code failed.
}
if (readbuffer[5] != sht30_crc8(readbuffer + 3, 2)) {
return 3; // check crc8 code failed.
}
uint16_t ST, SRH;
ST = conv8s_u16_be(readbuffer, 0);
SRH = conv8s_u16_be(readbuffer, 3);
double stemp = (double)ST * 17500.0 / 65535.0 - 4500.0;
*temp = (int32_t)stemp;
// Serial.print("SRH = "); Serial.println(SRH);
double shum = (double)SRH * 10000.0 / 65535.0;
*humi = (int32_t)shum;
return 0;
}
/** <!-- sht30_crc8 {{{1 --> CRC-8 formula from page 14 of SHT spec pdf
* Test data 0xBE, 0xEF should yield 0x92.
*
* Initialization data 0xFF
* Polynomial 0x31 (x8 + x5 +x4 +1)
* Final XOR 0x00
*/
uint8_t sht30_crc8(const uint8_t *data, int len) {
const uint8_t POLYNOMIAL(0x31);
uint8_t crc(0xFF);
for (int j = len; j; --j) {
crc ^= *data++;
for (int i = 8; i; --i) {
crc = (crc & 0x80) ? (crc << 1) ^ POLYNOMIAL : (crc << 1);
}
}
return crc;
}
/** <!-- setup - humidity sensor {{{1 -->
* 1. setup LED gpio.
* 2. setup sensor
*/
void setup() {
Serial.begin(115200);
Serial.println("peripherals: GPIO");
pinMode(GPIO_LED_R_PIN, OUTPUT);
pinMode(GPIO_LED_G_PIN, OUTPUT);
pinMode(GPIO_LED_B_PIN, OUTPUT);
digitalWrite(GPIO_LED_R_PIN, LOW);
digitalWrite(GPIO_LED_G_PIN, LOW);
digitalWrite(GPIO_LED_B_PIN, LOW);
Serial.println("peripherals: I2C");
Wire.begin(); // master
Serial.println("sensor: illuminance");
sht30_setup();
delay(32);
}
/** <!-- loop - humidity sensor {{{1 -->
* 1. blink LEDs
* 2. read and convert sensor.
* 3. output results, format is: x100[%RH], x100[degC]
*/
void loop() {
static bool blink = false;
int32_t humi, temp;
blink = !blink;
digitalWrite(GPIO_LED_R_PIN, blink ? HIGH: LOW);
digitalWrite(GPIO_LED_G_PIN, blink ? HIGH: LOW);
digitalWrite(GPIO_LED_B_PIN, blink ? HIGH: LOW);
delay(900);
int ret = sht30_readTempHumi(&humi, &temp);
Serial.print("sensor output:");
Serial.print(humi / 100.0);
Serial.print("[%RH],");
Serial.print(temp / 100.0);
Serial.print("[degC], return code: ");
Serial.println(ret);
}
// vi: ft=arduino:fdm=marker:et:sw=4:tw=80
So, I've earned my corned beef and cabbage dinner
.
This seems like a useful board to play with sensors and it supports 5V I2C levels.



