Created
June 1, 2016 22:34
-
-
Save mattiarossi/da69884f160cfa7c46c71d9603f44bee to your computer and use it in GitHub Desktop.
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
| #include <ESP8266WiFi.h> | |
| #include <OneWire.h> | |
| #include <DallasTemperature.h> | |
| #include <PubSubClient.h> | |
| //Def | |
| #define HVAC_TOSHIBA_DEBUG; // Un comment to access DEBUG information through Serial Interface | |
| #define ONE_WIRE_BUS 10 // DS18B20 on arduino pin10 corresponds to SD3 on ESP8266 Dev Board | |
| #define NUMROOMS 5 | |
| #define DELAY 60000 //Check temp every 10 sec | |
| int ledPin = 2; // GPIO2 | |
| WiFiClient espClient; | |
| PubSubClient client(espClient); | |
| OneWire oneWire(ONE_WIRE_BUS); | |
| DallasTemperature DS18B20(&oneWire); | |
| float prevTemp = 0; | |
| const char* MY_SSID = "WIFISSID"; | |
| const char* MY_PWD = "WIFIPWD"; | |
| int sent = 0; | |
| char mqtt_user[] = "mqttuser"; | |
| char mqtt_password[] = "mqttpasswd"; | |
| char mqtt_id[] = "esp8266-01"; | |
| const char* mqtt_server = "ipoftheserver"; | |
| const char * outTopic = "esp8266/01/out"; | |
| const char * pingTopic = "esp8266/01/ping"; | |
| char * statusTopic = "esp8266/01/status/00/00"; | |
| char * inTopic = "esp8266/01/in/#"; | |
| typedef struct roomHvac RoomHvac; | |
| unsigned long nextPingOn = 0; | |
| unsigned long pingDelay = 60000; | |
| byte probes[][8] = { | |
| { 0x28, 0x82, 0xEB, 0x35, 0x05, 0x00, 0x00, 0xCC }, | |
| { 0x28, 0xDD, 0x1F, 0x35, 0x05, 0x00, 0x00, 0x7F }, | |
| { 0x28, 0xB7, 0x8B, 0x34, 0x05, 0x00, 0x00, 0x54 }, | |
| { 0x28, 0x2B, 0x4C, 0x35, 0x05, 0x00, 0x00, 0x64 }, | |
| { 0x28, 0x4F, 0xC3, 0xA2, 0x04, 0x00, 0x00, 0x13 } | |
| }; | |
| float drift[5] = {0, 0, 0, 0, 0}; | |
| // Reconnect to the MQTT server in case of disconnect | |
| void reconnect() { | |
| // Loop until we're reconnected | |
| while (!client.connected()) { | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.println("Attempting MQTT reconnection..."); | |
| #endif | |
| if (WiFi.status() != WL_CONNECTED) | |
| { | |
| connectWifi(); | |
| } | |
| // Attempt to connect | |
| if (client.connect(mqtt_id, mqtt_user, mqtt_password)) { | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.println("reconnected"); | |
| #endif | |
| // Once connected, publish an announcement... | |
| client.publish(pingTopic, "2"); | |
| // ... and resubscribe | |
| client.subscribe(inTopic); | |
| } else { | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.print("failed, rc="); | |
| Serial.print(client.state()); | |
| Serial.println(" try again in 5 seconds"); | |
| // Wait 5 seconds before retrying | |
| #endif | |
| delay(15000); | |
| } | |
| } | |
| } | |
| int halfPeriodicTime; | |
| int IRpin; | |
| int khz; | |
| typedef enum HvacMode { | |
| HVAC_HOT, | |
| HVAC_COLD, | |
| HVAC_DRY, | |
| HVAC_FAN, // used for Panasonic only | |
| HVAC_AUTO | |
| } HvacMode_t; // HVAC MODE | |
| typedef enum HvacFanMode { | |
| FAN_SPEED_1, | |
| FAN_SPEED_2, | |
| FAN_SPEED_3, | |
| FAN_SPEED_4, | |
| FAN_SPEED_5, | |
| FAN_SPEED_AUTO, | |
| FAN_SPEED_SILENT | |
| } HvacFanMode_; // HVAC FAN MODE | |
| typedef enum HvacVanneMode { | |
| VANNE_AUTO, | |
| VANNE_H1, | |
| VANNE_H2, | |
| VANNE_H3, | |
| VANNE_H4, | |
| VANNE_H5, | |
| VANNE_AUTO_MOVE | |
| } HvacVanneMode_; // HVAC VANNE MODE | |
| typedef enum HvacWideVanneMode { | |
| WIDE_LEFT_END, | |
| WIDE_LEFT, | |
| WIDE_MIDDLE, | |
| WIDE_RIGHT, | |
| WIDE_RIGHT_END | |
| } HvacWideVanneMode_t; // HVAC WIDE VANNE MODE | |
| typedef enum HvacAreaMode { | |
| AREA_SWING, | |
| AREA_LEFT, | |
| AREA_AUTO, | |
| AREA_RIGHT | |
| } HvacAreaMode_t; // HVAC WIDE VANNE MODE | |
| typedef enum HvacProfileMode { | |
| NORMAL, | |
| QUIET, | |
| BOOST | |
| } HvacProfileMode_t; // HVAC PANASONIC OPTION MODE | |
| struct roomHvac | |
| { | |
| int temp; | |
| int state; // 0 - OFF 1 - ON | |
| HvacFanMode fanHvac; | |
| HvacMode modeHvac; | |
| int pin; | |
| float probeTemp; | |
| float oldTemp; | |
| }; | |
| void sendHvacToshiba( | |
| HvacMode , | |
| int , | |
| HvacFanMode , | |
| int , | |
| int | |
| ); | |
| typedef struct roomHvac RoomHvac; | |
| RoomHvac rooms[NUMROOMS]; | |
| void publishRoomStatus(int roomNo) { | |
| char b[10]; | |
| statusTopic[19] = '0' + roomNo; | |
| statusTopic[22] = '0'; | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.print("Sending update for room "); | |
| Serial.println(roomNo); | |
| Serial.println(); | |
| #endif | |
| sprintf(b, "%d", rooms[roomNo].state); | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.print("Publishing value "); | |
| Serial.print(b); | |
| Serial.print(" to Topic: "); | |
| Serial.println(statusTopic); | |
| #endif | |
| client.publish(statusTopic, b); | |
| statusTopic[22] = '1'; | |
| sprintf(b, "%d", rooms[roomNo].temp); | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.print("Publishing value "); | |
| Serial.print(b); | |
| Serial.print(" to Topic: "); | |
| Serial.println(statusTopic); | |
| #endif | |
| client.publish(statusTopic, b); | |
| statusTopic[22] = '2'; | |
| sprintf(b, "%d", (int)rooms[roomNo].modeHvac); | |
| client.publish(statusTopic, b); | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.print("Publishing value "); | |
| Serial.print(b); | |
| Serial.print(" to Topic: "); | |
| Serial.println(statusTopic); | |
| #endif | |
| statusTopic[22] = '3'; | |
| sprintf(b, "%d", (int)rooms[roomNo].fanHvac); | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.print("Publishing value "); | |
| Serial.print(b); | |
| Serial.print(" to Topic: "); | |
| Serial.println(statusTopic); | |
| #endif | |
| client.publish(statusTopic, b); | |
| statusTopic[22] = '4'; | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.print("Publishing value "); | |
| Serial.print(rooms[roomNo].probeTemp); | |
| Serial.print(" to Topic: "); | |
| Serial.println(statusTopic); | |
| #endif | |
| client.publish(statusTopic, f2s(rooms[roomNo].probeTemp, 2)); | |
| } | |
| void callback(char* topic, byte* payload, unsigned int length) { | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.print("Message arrived ["); | |
| Serial.print(topic); | |
| Serial.print("] "); | |
| for (int i = 0; i < length; i++) { | |
| Serial.print((char)payload[i]); | |
| } | |
| Serial.println(); | |
| #endif | |
| payload[length] = '\0'; | |
| int val = atoi((char *)payload); | |
| client.publish(outTopic, "received"); | |
| int roomNo = (int)topic[15] - 48; | |
| char commandRoom = topic[18]; | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.print("Received command for room:"); | |
| Serial.println(roomNo); | |
| Serial.print("Received command:"); | |
| Serial.println(commandRoom); | |
| Serial.print("Received val:"); | |
| Serial.println(val); | |
| #endif | |
| /* | |
| Rooms: | |
| 0: Sala | |
| 1: Studio | |
| 2: Camera PT | |
| 3: Camera NORD PP | |
| 4: Camera SUD PP | |
| Commands: | |
| 0: 0 = OFF 1 = ON | |
| 1: TEMP SETPOINT (17-30) | |
| 2: AC MODE: 0: Hot 1: Cold 2: Dry 4: Auto | |
| 3: FAN Mode: 0: 1 1: 2 2:3 3: 4 4: 5 5: AUTO | |
| */ | |
| if (roomNo >= 0 && roomNo <= NUMROOMS - 1 ) { | |
| switch (commandRoom) { | |
| case '0': | |
| if (val == 0 || val == 1) { | |
| rooms[roomNo].state = val; | |
| } | |
| break; | |
| case '1': | |
| if (val < 17) { | |
| val = 17; | |
| } | |
| if (val > 30) { | |
| val = 30; | |
| } | |
| rooms[roomNo].temp = val; | |
| break; | |
| case '2': | |
| if (val >= 0 && val <= 4) { | |
| rooms[roomNo].modeHvac = (HvacMode) val; | |
| } | |
| break; | |
| case '3': | |
| if (val >= 0 && val <= 5) { | |
| rooms[roomNo].fanHvac = (HvacFanMode)val; | |
| } | |
| break; | |
| default: | |
| break; | |
| } | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.println("Room Data:"); | |
| Serial.print("State: "); | |
| Serial.println(rooms[roomNo].state); | |
| Serial.print("Temp: "); | |
| Serial.println(rooms[roomNo].temp); | |
| Serial.print("Mode: "); | |
| Serial.println(rooms[roomNo].modeHvac); | |
| Serial.print("Fan: "); | |
| Serial.println(rooms[roomNo].fanHvac); | |
| #endif | |
| int offState = 0; | |
| if ( rooms[roomNo].state == 0) { | |
| offState = 1; | |
| } | |
| sendHvacToshiba(rooms[roomNo].modeHvac, rooms[roomNo].temp, rooms[roomNo].fanHvac, offState, rooms[roomNo].pin); | |
| //const char * statusTopic="esp8266/01/status/00/00"; | |
| publishRoomStatus(roomNo); | |
| } | |
| } | |
| // HVAC TOSHIBA_ | |
| #define HVAC_TOSHIBA_HDR_MARK 4400 | |
| #define HVAC_TOSHIBA_HDR_SPACE 4300 | |
| #define HVAC_TOSHIBA_BIT_MARK 560 | |
| #define HVAC_TOSHIBA_ONE_SPACE 1590 | |
| #define HVAC_MISTUBISHI_ZERO_SPACE 472 | |
| #define HVAC_TOSHIBA_RPT_MARK 440 | |
| #define HVAC_TOSHIBA_RPT_SPACE 7048 // Above original iremote limit | |
| /**************************************************************************** | |
| /* Send IR command to Toshiba HVAC - sendHvacToshiba | |
| /***************************************************************************/ | |
| void sendHvacToshiba( | |
| HvacMode HVAC_Mode, // Example HVAC_HOT | |
| int HVAC_Temp, // Example 21 (°c) | |
| HvacFanMode HVAC_FanMode, // Example FAN_SPEED_AUTO | |
| int OFF, // Example false | |
| int irPin | |
| ) | |
| { | |
| #define HVAC_TOSHIBA_DATALEN 9 | |
| IRpin = irPin; | |
| byte mask = 1; //our bitmask | |
| //F20D03FC0150000051 | |
| byte data[HVAC_TOSHIBA_DATALEN] = { 0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00 }; | |
| // data array is a valid trame, only byte to be chnaged will be updated. | |
| byte i; | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.println("Packet to send: "); | |
| for (i = 0; i < HVAC_TOSHIBA_DATALEN; i++) { | |
| Serial.print("_"); | |
| Serial.print(data[i], HEX); | |
| } | |
| Serial.println("."); | |
| #endif | |
| data[6] = 0x00; | |
| // Byte 7 - Mode | |
| switch (HVAC_Mode) | |
| { | |
| case HVAC_HOT: data[6] = (byte) B00000011; break; | |
| case HVAC_COLD: data[6] = (byte) B00000001; break; | |
| case HVAC_DRY: data[6] = (byte) B00000010; break; | |
| case HVAC_AUTO: data[6] = (byte) B00000000; break; | |
| default: break; | |
| } | |
| // Byte 7 - On / Off | |
| if (OFF) { | |
| data[6] = (byte) 0x07; // Turn OFF HVAC | |
| } else { | |
| // Turn ON HVAC (default) | |
| } | |
| // Byte 6 - Temperature | |
| // Check Min Max For Hot Mode | |
| byte Temp; | |
| if (HVAC_Temp > 30) { | |
| Temp = 30; | |
| } | |
| else if (HVAC_Temp < 17) { | |
| Temp = 17; | |
| } | |
| else { | |
| Temp = HVAC_Temp; | |
| }; | |
| data[5] = (byte) Temp - 17 << 4; | |
| // Byte 10 - FAN / VANNE | |
| switch (HVAC_FanMode) | |
| { | |
| case FAN_SPEED_1: data[6] = data[6] | (byte) B01000000; break; | |
| case FAN_SPEED_2: data[6] = data[6] | (byte) B01100000; break; | |
| case FAN_SPEED_3: data[6] = data[6] | (byte) B10000000; break; | |
| case FAN_SPEED_4: data[6] = data[6] | (byte) B10100000; break; | |
| case FAN_SPEED_5: data[6] = data[6] | (byte) B11000000; break; | |
| case FAN_SPEED_AUTO: data[6] = data[6] | (byte) B00000000; break; | |
| case FAN_SPEED_SILENT: data[6] = data[6] | (byte) B00000000; break;//No FAN speed SILENT for TOSHIBA so it is consider as Speed AUTO | |
| default: break; | |
| } | |
| // Byte 9 - CRC | |
| data[8] = 0; | |
| for (i = 0; i < HVAC_TOSHIBA_DATALEN - 1; i++) { | |
| data[HVAC_TOSHIBA_DATALEN - 1] = (byte) data[i] ^ data[HVAC_TOSHIBA_DATALEN - 1]; // CRC is a simple bits addition | |
| } | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.println("Packet to send: "); | |
| for (i = 0; i < HVAC_TOSHIBA_DATALEN; i++) { | |
| Serial.print("_"); Serial.print(data[i], HEX); | |
| } | |
| Serial.println("."); | |
| for (i = 0; i < HVAC_TOSHIBA_DATALEN ; i++) { | |
| Serial.print(data[i], BIN); Serial.print(" "); | |
| } | |
| Serial.println("."); | |
| #endif | |
| enableIROut(38); // 38khz | |
| space(0); | |
| for (int j = 0; j < 2; j++) { // For Toshiba IR protocol we have to send two time the packet data | |
| // Header for the Packet | |
| mark(HVAC_TOSHIBA_HDR_MARK); | |
| space(HVAC_TOSHIBA_HDR_SPACE); | |
| for (i = 0; i < HVAC_TOSHIBA_DATALEN; i++) { | |
| // Send all Bits from Byte Data in Forward Order (MSB) | |
| for (mask = 10000000; mask > 0; mask >>= 1) { //iterate through bit mask | |
| if (data[i] & mask) { // Bit ONE | |
| mark(HVAC_TOSHIBA_BIT_MARK); | |
| space(HVAC_TOSHIBA_ONE_SPACE); | |
| } | |
| else { // Bit ZERO | |
| mark(HVAC_TOSHIBA_BIT_MARK); | |
| space(HVAC_MISTUBISHI_ZERO_SPACE); | |
| } | |
| //Next bits | |
| } | |
| } | |
| // End of Packet and retransmission of the Packet | |
| mark(HVAC_TOSHIBA_RPT_MARK); | |
| space(HVAC_TOSHIBA_RPT_SPACE); | |
| space(0); // Just to be sure | |
| } | |
| } | |
| /**************************************************************************** | |
| /* enableIROut : Set global Variable for Frequency IR Emission | |
| /***************************************************************************/ | |
| void enableIROut(int khz) { | |
| // Enables IR output. The khz value controls the modulation frequency in kilohertz. | |
| halfPeriodicTime = 500 / khz; // T = 1/f but we need T/2 in microsecond and f is in kHz | |
| } | |
| /**************************************************************************** | |
| /* mark ( int time) | |
| /***************************************************************************/ | |
| void mark(int time) { | |
| // Sends an IR mark for the specified number of microseconds. | |
| // The mark output is modulated at the PWM frequency. | |
| long beginning = micros(); | |
| while (micros() - beginning < time) { | |
| digitalWrite(IRpin, HIGH); | |
| delayMicroseconds(halfPeriodicTime); | |
| digitalWrite(IRpin, LOW); | |
| delayMicroseconds(halfPeriodicTime); //38 kHz -> T = 26.31 microsec (periodic time), half of it is 13 | |
| } | |
| } | |
| /**************************************************************************** | |
| /* space ( int time) | |
| /***************************************************************************/ | |
| /* Leave pin off for time (given in microseconds) */ | |
| void space(int time) { | |
| // Sends an IR space for the specified number of microseconds. | |
| // A space is no output, so the PWM output is disabled. | |
| digitalWrite(IRpin, LOW); | |
| if (time > 0) delayMicroseconds(time); | |
| } | |
| /**************************************************************************** | |
| /* sendRaw (unsigned int buf[], int len, int hz) | |
| /***************************************************************************/ | |
| void sendRaw (unsigned int buf[], int len, int hz) | |
| { | |
| enableIROut(hz); | |
| for (int i = 0; i < len; i++) { | |
| if (i & 1) { | |
| space(buf[i]); | |
| } | |
| else { | |
| mark(buf[i]); | |
| } | |
| } | |
| space(0); // Just to be sure | |
| } | |
| /* Check the temperature data */ | |
| void tempTimer() { | |
| //Getting the temperature | |
| float temp = 0; | |
| for (int r = 0; r < NUMROOMS; r++) { | |
| rooms[r].oldTemp = rooms[r].probeTemp; | |
| rooms[r].probeTemp = readTemp(probes[r]) - drift[r]; | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.print("Room: "); | |
| Serial.print(r); | |
| Serial.print(" - Temperature: "); | |
| Serial.println(rooms[r].probeTemp); | |
| #endif | |
| if (rooms[r].probeTemp != rooms[r].oldTemp) { | |
| publishRoomStatus(r); | |
| } | |
| } | |
| } | |
| /* float to string | |
| f is the float to turn into a string | |
| p is the precision (number of decimals) | |
| return a string representation of the float. | |
| */ | |
| char *f2s(float f, int p) { | |
| char * pBuff; // use to remember which part of the buffer to use for dtostrf | |
| const int iSize = 10; // number of bufffers, one for each float before wrapping around | |
| static char sBuff[iSize][20]; // space for 20 characters including NULL terminator for each float | |
| static int iCount = 0; // keep a tab of next place in sBuff to use | |
| pBuff = sBuff[iCount]; // use this buffer | |
| if (iCount >= iSize - 1) { // check for wrap | |
| iCount = 0; // if wrapping start again and reset | |
| } | |
| else { | |
| iCount++; // advance the counter | |
| } | |
| return dtostrf(f, 0, p, pBuff); // call the library function | |
| } | |
| void setup() { | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.begin(115200); | |
| Serial.println("Sketch Started."); | |
| #endif | |
| IRpin = D0; | |
| khz = 38; | |
| halfPeriodicTime = 500 / khz; | |
| pinMode(IRpin, OUTPUT); | |
| for (int r = 0; r < NUMROOMS; r++) { | |
| /* | |
| struct roomHvac | |
| { | |
| int temp; | |
| int state; // 0 - OFF 1 - ON | |
| HvacFanMode fanHvac; | |
| HvacMode modeHvac; | |
| }; | |
| */ | |
| rooms[r].temp = 22; | |
| rooms[r].state = 0; | |
| rooms[r].fanHvac = FAN_SPEED_AUTO; | |
| rooms[r].modeHvac = HVAC_AUTO; | |
| } | |
| rooms[0].pin = D0; | |
| pinMode(D0, OUTPUT); | |
| rooms[1].pin = D1; | |
| pinMode(D1, OUTPUT); | |
| rooms[2].pin = D2; | |
| pinMode(D2, OUTPUT); | |
| rooms[3].pin = D3; | |
| pinMode(D3, OUTPUT); | |
| rooms[4].pin = D4; | |
| pinMode(D4, OUTPUT); | |
| connectWifi(); | |
| client.setServer(mqtt_server, 1883); | |
| client.setCallback(callback); | |
| if (client.connect(mqtt_id, mqtt_user, mqtt_password)) { | |
| client.publish(outTopic, "hello world"); | |
| client.subscribe(inTopic); | |
| } | |
| for (int r = 0; r < 5; r++) { | |
| publishRoomStatus(r); | |
| } | |
| } | |
| void loop() { | |
| float temp; | |
| if (WiFi.status() != WL_CONNECTED) | |
| { | |
| connectWifi(); | |
| } | |
| if (!client.connected()) { | |
| reconnect(); | |
| } | |
| client.loop(); | |
| unsigned long time = millis(); | |
| if (time > nextPingOn) { | |
| tempTimer(); | |
| client.publish(pingTopic, "1"); | |
| nextPingOn = time + pingDelay; | |
| } | |
| } | |
| void connectWifi() | |
| { | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.print("Connecting to " + *MY_SSID); | |
| #endif | |
| WiFi.begin(MY_SSID, MY_PWD); | |
| while (WiFi.status() != WL_CONNECTED) { | |
| delay(1000); | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.print("."); | |
| #endif | |
| } | |
| #ifdef HVAC_TOSHIBA_DEBUG | |
| Serial.println(""); | |
| Serial.print("Connected to "); | |
| Serial.println(MY_SSID); | |
| Serial.print("IP address: "); | |
| Serial.println(WiFi.localIP()); | |
| #endif | |
| }//end connect | |
| float readTemp(byte *addressDs1820) { | |
| byte i; | |
| byte present = 0; | |
| byte type_s; | |
| byte data[12]; | |
| byte *addr; | |
| float celsius; | |
| /* | |
| if ( !ds.search(addr)) { | |
| ds.reset_search(); | |
| delay(250); | |
| return; | |
| } | |
| */ | |
| addr = addressDs1820; | |
| if (OneWire::crc8(addr, 7) != addr[7]) { | |
| return -1; | |
| } | |
| // the first ROM byte indicates which chip | |
| switch (addr[0]) { | |
| case 0x10: | |
| type_s = 1; | |
| break; | |
| case 0x28: | |
| type_s = 0; | |
| break; | |
| case 0x22: | |
| type_s = 0; | |
| break; | |
| default: | |
| return -1; | |
| } | |
| oneWire.reset(); | |
| oneWire.select(addr); | |
| oneWire.write(0x44, 1); // start conversion, with parasite power on at the end | |
| delay(1000); // maybe 750ms is enough, maybe not | |
| // we might do a ds.depower() here, but the reset will take care of it. | |
| present = oneWire.reset(); | |
| oneWire.select(addr); | |
| oneWire.write(0xBE); // Read Scratchpad | |
| for ( i = 0; i < 9; i++) { // we need 9 bytes | |
| data[i] = oneWire.read(); | |
| } | |
| // Convert the data to actual temperature | |
| // because the result is a 16 bit signed integer, it should | |
| // be stored to an "int16_t" type, which is always 16 bits | |
| // even when compiled on a 32 bit processor. | |
| int16_t raw = (data[1] << 8) | data[0]; | |
| if (type_s) { | |
| raw = raw << 3; // 9 bit resolution default | |
| if (data[7] == 0x10) { | |
| // "count remain" gives full 12 bit resolution | |
| raw = (raw & 0xFFF0) + 12 - data[6]; | |
| } | |
| } else { | |
| byte cfg = (data[4] & 0x60); | |
| // at lower res, the low bits are undefined, so let's zero them | |
| if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms | |
| else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms | |
| else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms | |
| //// default is 12 bit resolution, 750 ms conversion time | |
| } | |
| celsius = (float)raw / 16.0; | |
| // fahrenheit = celsius * 1.8 + 32.0; | |
| return celsius; | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment