Created
March 5, 2014 18:14
-
-
Save TechplexEngineer/9373080 to your computer and use it in GitHub Desktop.
Helpful code for using Microchip's TC74 I2C temperature sensors on the Raspberry Pi
This file contains hidden or 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
| /*! | |
| * @file | |
| * | |
| * @brief Library for the TC47A* I2C temperature sensors | |
| * | |
| * @author Blake Bourque | |
| * | |
| * @date Mar 5, 2014 | |
| * | |
| * Provides readTempInC and readTempInF | |
| * | |
| */ | |
| #include <stdio.h> //*printf, pclose/popen | |
| #include <string.h> //strcpy | |
| #include <stdlib.h> //strtol | |
| #include "TC74.h" | |
| // Private functions | |
| int exec(char *command, char *out, int out_len); | |
| float c2f(float f); | |
| // Public function documented in header | |
| int readTempInC(int bus, TC74_t addy) | |
| { | |
| #define C_LEN 20 //length of command | |
| #define B_LEN 3 //length of bus | |
| #define A_LEN 10 //length of addy | |
| #define PADD 6 //leave some extra space | |
| #define T_LEN 6 //Max length of temperature string | |
| char i2c_command[A_LEN+B_LEN+C_LEN+PADD]; | |
| strncpy(i2c_command, "/usr/sbin/i2cget -y", 20); | |
| if (bus == 1) { | |
| strncat(i2c_command, " 1", B_LEN); | |
| } | |
| else if (bus == 0) { | |
| strncat(i2c_command, " 0", B_LEN); | |
| } | |
| else { | |
| fprintf(stderr, "Valid values for bus are [0,1] %d is invalid.\n", bus); | |
| return -1; | |
| } | |
| char addystr[A_LEN]; | |
| int ret = snprintf(addystr, A_LEN, " 0x%x", addy); | |
| if (ret < 0) { | |
| fprintf(stderr, "Unable to generate command string.\n"); | |
| return -2; | |
| } | |
| else if (ret > A_LEN) { | |
| fprintf(stderr, "%d characters were truncated.\n", ret-A_LEN); | |
| } | |
| strncat(i2c_command, addystr, A_LEN); | |
| //printf("%s\n", i2c_command); | |
| char temp[T_LEN]; | |
| ret = exec(i2c_command, temp, T_LEN); | |
| if (ret < 0) | |
| { | |
| return -3; | |
| } | |
| //parse the temperature | |
| return strtol(temp, NULL, 16); //@todo This might not handle negative tempertatures well | |
| } | |
| // Public function documented in header | |
| float readTempInF(int bus, TC74_t addy) | |
| { | |
| int ret = readTempInC(bus, addy); //@todo what happens to negative return values | |
| return c2f(ret); | |
| } | |
| /** | |
| * Execute the command on the shell and give the first out_len characters from the | |
| * first line of output to the caller by placing them in the caller allocated buffer. | |
| * @param command command to run on the shell | |
| * @param out a caller allocated buffer of out_len length | |
| * @param out_len the max number of characters to return | |
| * @return 0 on success, < 0 on error | |
| */ | |
| int exec(char *command, char *out, int out_len) | |
| { | |
| FILE *fp; | |
| //Open the command for reading. | |
| fp = popen(command, "r"); | |
| if (fp == NULL) { | |
| fprintf(stderr, "Failed to run command %s\n", command); | |
| return -1; | |
| } | |
| // Read the output a line at a time - output it. | |
| // while (fgets(path, sizeof(path)-1, fp) != NULL) { | |
| // printf("%s", path); | |
| // } | |
| //read the first line and send it back to the caller | |
| char *ret = fgets(out, out_len-1, fp); | |
| if (ret == NULL) | |
| { | |
| fprintf(stderr, "Unable to read output from command %s\n", command); | |
| return -2; | |
| } | |
| //close | |
| pclose(fp); | |
| return 0; | |
| } | |
| /** | |
| * Convert Celsius to Fahrenheit | |
| * @param c Celsius temperature | |
| * @return Fahrenheit temperature | |
| */ | |
| float c2f(float c) | |
| { | |
| float _temp = c*9.0; | |
| _temp /= 5; | |
| _temp += 32; | |
| return _temp; | |
| } |
This file contains hidden or 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
| /*! | |
| * @file | |
| * | |
| * @brief Library for the TC47A* I2C temperature sensors | |
| * | |
| * @author Blake Bourque | |
| * | |
| * @date Mar 5, 2014 | |
| * | |
| * Provides readTempInC and readTempInF (header) | |
| * | |
| */ | |
| #ifndef __TC74_h__ | |
| #define __TC74_h__ | |
| typedef enum { | |
| TC74A0 = 0x48, | |
| TC74A1 = 0x49, | |
| TC74A2 = 0x4a, | |
| TC74A3 = 0x4b, | |
| TC74A4 = 0x4c, | |
| TC74A5 = 0x4d, | |
| TC74A6 = 0x4e, | |
| TC74A7 = 0x4f | |
| } TC74_t; | |
| /** | |
| * Reads the temperature from the sensor at address on the given bus. | |
| * Accurate to plus or minus 2 deg C. | |
| * @param bus 0 or 1: RPIv2 bus 1 is broken out on P1 header | |
| * @param addy address of a TC74 sensor | |
| * @return temperature in Celsius | |
| */ | |
| int readTempInC(int bus, TC74_t addy); | |
| /** | |
| * Reads the temperature from the sensor at address on the given bus and converts | |
| * the temp to Fahrenheit. | |
| * @param bus 0 or 1: RPIv2 bus 1 is broken out on P1 header | |
| * @param addy address of a TC74 sensor | |
| * @return temperature in Fahrenheit | |
| */ | |
| float readTempInF(int bus, TC74_t addy); | |
| #endif //__TC74_h__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment