Created
March 30, 2016 07:57
-
-
Save user890104/a2a7d0dc03b1abf4a9f895624ae64102 to your computer and use it in GitHub Desktop.
Si7021 collecting and reporting data to thingspeak.com
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#include <errno.h> | |
#include <sys/ioctl.h> | |
#include <linux/i2c-dev.h> | |
#define BYTES2SHORT(X) (X[0] << 8 | X[1]) | |
enum si7021_cmd_id { | |
MEAS_HUM, | |
MEAS_TEMP, | |
READ_TEMP, | |
RESET, | |
WRITE_USER_REG, | |
READ_USER_REG, | |
WRITE_HEATER_REG, | |
READ_HEATER_REG, | |
READ_SN_1, | |
READ_SN_2, | |
READ_FWREV, | |
SI7021_CMDS_COUNT | |
}; | |
const char **si7021_cmd; | |
unsigned int i2c_rw(int file, const char *wdata, size_t wlen, char *rdata, size_t rlen) { | |
if (wlen) { | |
if (write(file, wdata, wlen) != wlen) { | |
perror("write"); | |
return 1; | |
} | |
} | |
if (rlen) { | |
int retries = 10; | |
int result = read(file, rdata, rlen); | |
while ( | |
result == -1 && // read error | |
errno == ENXIO && // NACK | |
(--retries > 0) | |
) { | |
result = read(file, rdata, rlen); // retry | |
usleep(5000); // wait 5 ms | |
} | |
if (result != rlen) { | |
perror("read"); | |
return 2; | |
} | |
} | |
return 0; | |
} | |
int si7021_print_part(int file) { | |
char resp[6]; | |
if (i2c_rw(file, si7021_cmd[READ_SN_2], 2, resp, 1)) { | |
return 1; | |
} | |
fputs("PART: ", stderr); | |
switch (resp[0]) { | |
case 0x00: | |
case 0xFF: | |
fputs("Engineering sample", stderr); | |
break; | |
case 0x0D: | |
fputs("Si7013", stderr); | |
break; | |
case 0x14: | |
fputs("Si7020", stderr); | |
break; | |
case 0x15: | |
fputs("Si7021", stderr); | |
break; | |
default: | |
fputs("UNKNOWN", stderr); | |
break; | |
} | |
fputs("\n", stderr); | |
return 0; | |
} | |
int si7021_print_sn(int file) { | |
char resp[8]; | |
if (i2c_rw(file, si7021_cmd[READ_SN_1], 2, resp, 8)) { | |
return 1; | |
} | |
fprintf(stderr, "SN: %02x%02x%02x%02x\n", resp[0], resp[2], resp[4], resp[6]); | |
return 0; | |
} | |
int si7021_print_fwrev(int file) { | |
char resp; | |
if (i2c_rw(file, si7021_cmd[READ_FWREV], 2, &resp, 1)) { | |
return 1; | |
} | |
fputs("FWREV: ", stderr); | |
switch (resp) { | |
case 0xFF: | |
fputs("1.0", stderr); | |
break; | |
case 0x20: | |
fputs("2.0", stderr); | |
break; | |
default: | |
fputs("UNKNOWN", stderr); | |
break; | |
} | |
fputs("\n", stderr); | |
return 0; | |
} | |
int si7021_get_env(int file, char *buf) { | |
char resp[3]; | |
if (i2c_rw(file, si7021_cmd[MEAS_HUM], 1, resp, 3)) { | |
return 1; | |
} | |
float hum = 125.0 * BYTES2SHORT(resp) / 65536 - 6; | |
if (i2c_rw(file, si7021_cmd[READ_TEMP], 1, resp, 2)) { | |
return 1; | |
} | |
float temp = 175.72 * BYTES2SHORT(resp) / 65536 - 46.85; | |
fprintf(stderr, "T: %f°C\nH: %f%%\n", temp, hum); | |
char fields[64]; | |
sprintf(fields, "&field1=%f&field2=%f", temp, hum); | |
strcat(buf, fields); | |
return 0; | |
} | |
short axp209_get_value(int file, char request[2], unsigned char bits) { | |
char buffer; | |
short result; | |
if (i2c_rw(file, request, 1, &buffer, 1)) { | |
return 0xffff; | |
} | |
result = buffer << bits; | |
if (i2c_rw(file, request + 1, 1, &buffer, 1)) { | |
return 0xffff; | |
} | |
result |= buffer; | |
//fprintf(stderr, "READ: 0x%04x = %d\n", result, result); | |
return result; | |
} | |
int axp209_get_value_scaled(int file, char request[2], unsigned char bits, float step, float *result) { | |
short value = axp209_get_value(file, request, bits); | |
if (value == 0xffff) { | |
return 1; | |
} | |
*result = step * value / 1000; | |
return 0; | |
} | |
int axp209_get_vbus_voltage(int file, float *result) { | |
return axp209_get_value_scaled(file, "\x5A\x5B", 4, 1.7, result); | |
} | |
int axp209_get_vbus_current(int file, float *result) { | |
return axp209_get_value_scaled(file, "\x5C\x5D", 4, 0.375, result); | |
} | |
int axp209_get_temperature(int file, float *result) { | |
short value = axp209_get_value(file, "\x5E\x5F", 4); | |
if (value == 0xffff) { | |
return 1; | |
} | |
*result = 0.1 * value - 144.7; | |
return 0; | |
} | |
int axp209_get_battery_voltage(int file, float *result) { | |
return axp209_get_value_scaled(file, "\x78\x79", 4, 1.1, result); | |
} | |
int axp209_get_charge_current(int file, float *result) { | |
return axp209_get_value_scaled(file, "\x7A\x7B", 4, 0.5, result); | |
} | |
int axp209_get_discharge_current(int file, float *result) { | |
return axp209_get_value_scaled(file, "\x7C\x7D", 5, 0.5, result); | |
} | |
int axp209_get_ipsout_voltage(int file, float *result) { | |
return axp209_get_value_scaled(file, "\x7E\x7F", 4, 1.4, result); | |
} | |
int axp209_get_data(int file, char *buf) { | |
float value; | |
if (axp209_get_vbus_voltage(file, &value) == 0) { | |
fprintf(stderr, "Uvbus: %.4fV\n", value); | |
char fields[64]; | |
sprintf(fields, "&field6=%.4f", value); | |
strcat(buf, fields); | |
} | |
if (axp209_get_vbus_current(file, &value) == 0) { | |
fprintf(stderr, "Ivbus: %.6fA\n", value); | |
char fields[64]; | |
sprintf(fields, "&field7=%.6f", value); | |
strcat(buf, fields); | |
} | |
if (axp209_get_temperature(file, &value) == 0) { | |
fprintf(stderr, "Tchip: %.1f°C\n", value); | |
char fields[64]; | |
sprintf(fields, "&field3=%.1f", value); | |
strcat(buf, fields); | |
} | |
if (axp209_get_battery_voltage(file, &value) == 0) { | |
fprintf(stderr, "Ubatt: %.4fV\n", value); | |
char fields[64]; | |
sprintf(fields, "&field4=%.4f", value); | |
strcat(buf, fields); | |
} | |
if (axp209_get_charge_current(file, &value) == 0) { | |
fprintf(stderr, "Icharge: %.4fA\n", value); | |
char fields[64]; | |
sprintf(fields, "&field5=%.4f", value); | |
strcat(buf, fields); | |
} | |
if (axp209_get_discharge_current(file, &value) == 0) { | |
fprintf(stderr, "Idischarge: %.4fA\n", value); | |
char fields[64]; | |
sprintf(fields, "&field8=%.4f", value); | |
strcat(buf, fields); | |
} | |
if (axp209_get_ipsout_voltage(file, &value) == 0) { | |
fprintf(stderr, "Uipsout: %.4fV\n", value); | |
//char fields[64]; | |
//sprintf(fields, "&field5=%.4f", value); | |
//strcat(buf, fields); | |
} | |
return 0; | |
} | |
int i2c_connect(unsigned char i2c_id, unsigned char addr) { | |
char filename[14]; | |
strcpy(filename, "/dev/i2c-"); | |
char id[5]; | |
sprintf(id, "%u", i2c_id); | |
strcat(filename, id); | |
fputs(filename, stderr); | |
fputs("\n", stderr); | |
int file; | |
if ((file = open(filename, O_RDWR)) < 0) { | |
perror("open"); | |
return -1; | |
} | |
if (ioctl(file, I2C_SLAVE, addr) < 0) { | |
perror("ioctl I2C_SLAVE"); | |
if (ioctl(file, I2C_SLAVE_FORCE, addr) < 0) { | |
perror("ioctl I2C_SLAVE_FORCE"); | |
close(file); | |
return -1; | |
} | |
} | |
return file; | |
} | |
void si7021_write_data(char *buf) { | |
si7021_cmd = calloc(SI7021_CMDS_COUNT, sizeof(char *)); | |
si7021_cmd[MEAS_HUM] = "\xF5"; | |
si7021_cmd[MEAS_TEMP] = "\xF3"; | |
si7021_cmd[READ_TEMP] = "\xE0"; | |
si7021_cmd[RESET] = "\xFE"; | |
si7021_cmd[WRITE_USER_REG] = "\xE6"; | |
si7021_cmd[READ_USER_REG] = "\xE7"; | |
si7021_cmd[WRITE_HEATER_REG] = "\x51"; | |
si7021_cmd[READ_HEATER_REG] = "\x11"; | |
si7021_cmd[READ_SN_1] = "\xFA\x0F"; | |
si7021_cmd[READ_SN_2] = "\xFC\xC9"; | |
si7021_cmd[READ_FWREV] = "\x84\xB8"; | |
int file = i2c_connect(1, 0x40); | |
if (file == -1) { | |
return; | |
} | |
si7021_print_part(file); | |
si7021_print_sn(file); | |
si7021_print_fwrev(file); | |
si7021_get_env(file, buf); | |
close(file); | |
} | |
void axp209_write_data(char *buf) { | |
int file = i2c_connect(0, 0x34); | |
if (file == -1) { | |
return; | |
} | |
axp209_get_data(file, buf); | |
close(file); | |
} | |
int main(int argc, char **argv) { | |
char buf[2048]; | |
strcpy(buf, "http://api.thingspeak.com/update?api_key=XXXXXXXXXXXXXXXX"); | |
si7021_write_data(buf); | |
axp209_write_data(buf); | |
puts(buf); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
while [ 1 ] | |
do | |
wget -qO/dev/null "$(/home/chip/i2c/report 2>/dev/null)" | |
sleep 15 | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment