Include first driver: SHT31
Make I2C reads blocking w/ timeout Add SHT31 driver, roughly :) Fix mg_time() to return a double.
This commit is contained in:
		
							
								
								
									
										132
									
								
								src/mgos_sht31.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								src/mgos_sht31.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,132 @@ | ||||
| /* | ||||
|  * Copyright 2018 Google Inc. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| #include "mgos.h" | ||||
| #include "mgos_sht31_internal.h" | ||||
| #include "mgos_i2c.h" | ||||
|  | ||||
| // Private functions follow | ||||
| static bool mgos_sht31_cmd(struct mgos_sht31 *sensor, uint16_t cmd) { | ||||
|   uint8_t data[2]; | ||||
|  | ||||
|   if (!sensor || !sensor->i2c) | ||||
|     return false; | ||||
|  | ||||
|   data[0]=cmd>>8; | ||||
|   data[1]=cmd&0xFF; | ||||
|   if (!mgos_i2c_write(sensor->i2c, sensor->i2caddr, data, 2, true)) { | ||||
|     LOG(LL_ERROR, ("I2C=0x%02x cmd=%u (0x%04x) write error", sensor->i2caddr, cmd, cmd)); | ||||
|     return false; | ||||
|   } | ||||
|   LOG(LL_DEBUG, ("I2C=0x%02x cmd=%u (0x%04x) write success", sensor->i2caddr, cmd, cmd)); | ||||
|  | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| static uint8_t 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; | ||||
| } | ||||
| // Private functions end | ||||
|  | ||||
| // Public functions follow | ||||
| struct mgos_sht31 *mgos_sht31_create(struct mgos_i2c *i2c, uint8_t i2caddr) { | ||||
|   struct mgos_sht31 *sensor; | ||||
|  | ||||
|   if (!i2c) return NULL; | ||||
|  | ||||
|   sensor=calloc(1, sizeof(struct mgos_sht31)); | ||||
|   if (!sensor) return NULL; | ||||
|   sensor->i2caddr=i2caddr; | ||||
|   sensor->i2c=i2c; | ||||
|   sensor->last_read_time=0; | ||||
|  | ||||
|   mgos_sht31_cmd(sensor, MGOS_SHT31_SOFTRESET); | ||||
|   return sensor; | ||||
| } | ||||
|  | ||||
| void mgos_sht31_destroy(struct mgos_sht31 **sensor) { | ||||
|   if (!*sensor) return; | ||||
|   free (*sensor); | ||||
|   *sensor=NULL; | ||||
|   return; | ||||
| } | ||||
|  | ||||
| bool mgos_sht31_read(struct mgos_sht31 *sensor) { | ||||
|   double now = mg_time(); | ||||
|  | ||||
|   if (!sensor || !sensor->i2c) | ||||
|     return false; | ||||
|  | ||||
|   if (now - sensor->last_read_time < MGOS_SHT31_READ_DELAY) { | ||||
|     return true; | ||||
|   } | ||||
|   // Read out sensor data here  | ||||
|   // | ||||
|   uint8_t data[6]; | ||||
|   float humidity, temperature; | ||||
|  | ||||
|   mgos_sht31_cmd(sensor, MGOS_SHT31_MEAS_HIGHREP); | ||||
|  | ||||
|   mgos_usleep(500); | ||||
|  | ||||
|   if (!mgos_i2c_read(sensor->i2c, sensor->i2caddr, data, 6, true)) | ||||
|     return false; | ||||
|  | ||||
|   // Check CRC8 checksums | ||||
|   if ((data[2]!=crc8(data, 2)) || (data[5]!=crc8(data+3, 2))) | ||||
|     return false; | ||||
|  | ||||
|   temperature = data[0]*256 + data[1]; | ||||
|   temperature *= 175; | ||||
|   temperature /= 0xffff; | ||||
|   temperature -= 45; | ||||
|   sensor->temperature = temperature; | ||||
|  | ||||
|   humidity = data[3] * 256 + data[4]; | ||||
|   humidity *= 100; | ||||
|   humidity /= 0xFFFF; | ||||
|   sensor->humidity = humidity; | ||||
|  | ||||
|   LOG(LL_DEBUG, ("temperature=%.2fC humidity=%.1f%%", sensor->temperature, sensor->humidity)); | ||||
|   sensor->last_read_time=now; | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| float mgos_sht31_getTemperature(struct mgos_sht31 *sensor) { | ||||
|   if (!mgos_sht31_read(sensor)) return NAN; | ||||
|  | ||||
|   return sensor->temperature; | ||||
| } | ||||
|  | ||||
| float mgos_sht31_getHumidity(struct mgos_sht31 *sensor) { | ||||
|   if (!mgos_sht31_read(sensor)) return NAN; | ||||
|  | ||||
|   return sensor->humidity; | ||||
| } | ||||
|  | ||||
| bool mgos_sht31_i2c_init(void) { | ||||
|   return true; | ||||
| } | ||||
| // Public functions end | ||||
		Reference in New Issue
	
	Block a user