Automatic/Manual lights+AC connected over Wifi

Dependents:   ACandLightsandWifi ACandLightsandWifi

Fork of DS1820 by Michael Hagberg

Files at this revision

API Documentation at this revision

Comitter:
jzacaroli
Date:
Fri Jun 17 12:38:22 2016 +0000
Parent:
2:ee820a991b95
Commit message:
AC + Lights + Wifi

Changed in this revision

DS1820.cpp Show annotated file Show diff for this revision Revisions of this file
DS1820.h Show annotated file Show diff for this revision Revisions of this file
diff -r ee820a991b95 -r cf4f0ea711a7 DS1820.cpp
--- a/DS1820.cpp	Thu Dec 15 19:07:36 2011 +0000
+++ b/DS1820.cpp	Fri Jun 17 12:38:22 2016 +0000
@@ -0,0 +1,390 @@
+#include "DS1820.h"
+#include "mbed.h"
+ 
+// Global variables shared between all DS1820 objects
+bool DS1820_done_flag;
+int  DS1820_last_descrepancy;
+char DS1820_search_Rom[8];
+ 
+ 
+DS1820::DS1820 (PinName data_pin, PinName power_pin) : _datapin(data_pin), _parasitepin(power_pin) {
+    int byte_counter;
+    _parasite_power = true;
+    for(byte_counter=0;byte_counter<8;byte_counter++)
+        Rom[byte_counter] = 0xFF;
+    for(byte_counter=0;byte_counter<9;byte_counter++)
+        RAM[byte_counter] = 0x00;
+}
+DS1820::DS1820 (PinName data_pin) : _datapin(data_pin), _parasitepin(NC) {
+    int byte_counter;
+    _parasite_power = false;
+    for(byte_counter=0;byte_counter<8;byte_counter++)
+        Rom[byte_counter] = 0xFF;
+    for(byte_counter=0;byte_counter<9;byte_counter++)
+        RAM[byte_counter] = 0x00;
+}
+ 
+bool DS1820::onewire_reset() {
+// This will return false if no devices are present on the data bus
+    bool presence=false;
+    _datapin.output();
+    _datapin = 0;           // bring low for 500 us
+    wait_us(500);
+    _datapin.input();       // let the data line float high
+    wait_us(90);            // wait 90us
+    if (_datapin.read()==0) // see if any devices are pulling the data line low
+        presence=true;
+    wait_us(410);
+    return presence;
+}
+ 
+void DS1820::onewire_bit_out (bool bit_data) {
+    _datapin.output();
+    _datapin = 0;
+    wait_us(5);
+    if (bit_data) {
+        _datapin.input(); // bring data line high
+        wait_us(55);
+    } else {
+        wait_us(55);            // keep data line low
+        _datapin.input();
+    }
+}
+ 
+void DS1820::onewire_byte_out(char data) { // output data character (least sig bit first).
+    int n;
+    for (n=0; n<8; n++) {
+        onewire_bit_out(data & 0x01);
+        data = data >> 1; // now the next bit is in the least sig bit position.
+    }
+}
+ 
+bool DS1820::onewire_bit_in() {
+    bool answer;
+    _datapin.output();
+    _datapin = 0;
+    wait_us(5);
+    _datapin.input();
+    wait_us(5);
+    answer = _datapin.read();
+    wait_us(50);
+    return answer;
+}
+ 
+char DS1820::onewire_byte_in() { // read byte, least sig byte first
+    char answer = 0x00;
+    int i;
+    for (i=0; i<8; i++) {
+        answer = answer >> 1; // shift over to make room for the next bit
+        if (onewire_bit_in())
+            answer = answer | 0x80; // if the data port is high, make this bit a 1
+    }
+    return answer;
+}
+ 
+bool DS1820::search_Rom() {
+    return search_Rom_routine(0xF0);    // Search Rom command
+}
+ 
+bool DS1820::search_alarm() {
+    return search_Rom_routine(0xEC);    // Search Alarm command
+}
+ 
+bool DS1820::search_Rom_routine(char command) {
+    extern bool DS1820_done_flag;
+    extern int DS1820_last_descrepancy;
+    extern char DS1820_search_Rom[8];
+    int descrepancy_marker, Rom_bit_index;
+    bool return_value, Bit_A, Bit_B;
+    char byte_counter, bit_mask;
+ 
+    return_value=false;
+    if (!DS1820_done_flag) {
+        if (!onewire_reset()) {
+            DS1820_last_descrepancy = 0; // no devices present
+        } else {
+            Rom_bit_index=1;
+            descrepancy_marker=0;
+            onewire_byte_out(command); // Search Rom command or Search Alarm command
+            byte_counter = 0;
+            bit_mask = 0x01;
+            while (Rom_bit_index<=64) {
+                Bit_A = onewire_bit_in();
+                Bit_B = onewire_bit_in();
+                if (Bit_A & Bit_B) {
+                    descrepancy_marker = 0; // data read error, this should never happen
+                    Rom_bit_index = 0xFF;
+                } else {
+                    if (Bit_A | Bit_B) {
+                        // Set Rom bit to Bit_A
+                        if (Bit_A) {
+                            DS1820_search_Rom[byte_counter] = DS1820_search_Rom[byte_counter] | bit_mask; // Set Rom bit to one
+                        } else {
+                            DS1820_search_Rom[byte_counter] = DS1820_search_Rom[byte_counter] & ~bit_mask; // Set Rom bit to zero
+                        }
+                    } else {
+                        // both bits A and B are low, so there are two or more devices present
+                        if ( Rom_bit_index == DS1820_last_descrepancy ) {
+                            DS1820_search_Rom[byte_counter] = DS1820_search_Rom[byte_counter] | bit_mask; // Set Rom bit to one
+                        } else {
+                            if ( Rom_bit_index > DS1820_last_descrepancy ) {
+                                DS1820_search_Rom[byte_counter] = DS1820_search_Rom[byte_counter] & ~bit_mask; // Set Rom bit to zero
+                                descrepancy_marker = Rom_bit_index;
+                            } else {
+                                if (( DS1820_search_Rom[byte_counter] & bit_mask) == 0x00 )
+                                    descrepancy_marker = Rom_bit_index;
+                            }
+                        }
+                    }
+                    onewire_bit_out (DS1820_search_Rom[byte_counter] & bit_mask);
+                    Rom_bit_index++;
+                    if (bit_mask & 0x80) {
+                        byte_counter++;
+                        bit_mask = 0x01;
+                    } else {
+                        bit_mask = bit_mask << 1;
+                    }
+                }
+            }
+            DS1820_last_descrepancy = descrepancy_marker;
+            if (Rom_bit_index != 0xFF) {
+                for(byte_counter=0;byte_counter<8;byte_counter++)
+                    Rom[byte_counter] = DS1820_search_Rom[byte_counter];
+                return_value = true;
+            }
+        }
+        if (DS1820_last_descrepancy == 0)
+            DS1820_done_flag = true;
+    }
+    return return_value;
+}
+ 
+void DS1820::search_Rom_setup() {
+    extern bool DS1820_done_flag;
+    extern int DS1820_last_descrepancy;
+    extern char DS1820_search_Rom[8];
+    DS1820_done_flag = false;
+    DS1820_last_descrepancy = 0;
+    int i;
+    for (i=0; i<8; i++)
+        DS1820_search_Rom[i]=0x00;
+}
+ 
+void DS1820::read_Rom(){
+    // NOTE: This command can only be used when there is one DS1820 on the bus. If this command
+    // is used when there is more than one slave present on the bus, a data collision will occur
+    // when all the DS1820s attempt to respond at the same time.
+    int i;
+    onewire_reset();
+    onewire_byte_out(0x33);   // Read Rom id
+    for (i=0; i<8; i++)
+        Rom[i]=onewire_byte_in();
+}
+ 
+void DS1820::match_Rom() {
+// Used to select a specific device
+    int i;
+    onewire_reset();
+    onewire_byte_out( 0x55);  //Match Rom command
+    for (i=0;i<8;i++)
+        onewire_byte_out(Rom[i]);
+}
+ 
+void DS1820::skip_Rom() {
+    onewire_reset();
+    onewire_byte_out(0xCC);   // Skip Rom command
+}
+ 
+bool DS1820::Rom_checksum_error() {
+    char CRC=0x00;
+    int i;
+    for(i=0;i<7;i++) // Only going to shift the lower 7 bytes
+        CRC = CRC_byte(CRC, Rom[i]);
+    // After 7 bytes CRC should equal the 8th byte (Rom CRC)
+    return (CRC!=Rom[7]); // will return true if there is a CRC checksum error         
+}
+ 
+bool DS1820::RAM_checksum_error() {
+    char CRC=0x00;
+    int i;
+    read_RAM();
+    for(i=0;i<8;i++) // Only going to shift the lower 8 bytes
+        CRC = CRC_byte(CRC, RAM[i]);
+    // After 8 bytes CRC should equal the 9th byte (RAM CRC)
+    return (CRC!=RAM[8]); // will return true if there is a CRC checksum error         
+}
+ 
+char DS1820::CRC_byte (char CRC, char byte ) {
+    int j;
+    for(j=0;j<8;j++) {
+        if ((byte & 0x01 ) ^ (CRC & 0x01)) {
+            // DATA ^ LSB CRC = 1
+            CRC = CRC>>1;
+            // Set the MSB to 1
+            CRC = CRC | 0x80;
+            // Check bit 3
+            if (CRC & 0x04) {
+                CRC = CRC & 0xFB; // Bit 3 is set, so clear it
+            } else {
+                CRC = CRC | 0x04; // Bit 3 is clear, so set it
+            }
+            // Check bit 4
+            if (CRC & 0x08) {
+                CRC = CRC & 0xF7; // Bit 4 is set, so clear it
+            } else {
+                CRC = CRC | 0x08; // Bit 4 is clear, so set it
+            }
+        } else {
+            // DATA ^ LSB CRC = 0
+            CRC = CRC>>1;
+            // clear MSB
+            CRC = CRC & 0x7F;
+            // No need to check bits, with DATA ^ LSB CRC = 0, they will remain unchanged
+        }
+        byte = byte>>1;
+    }
+return CRC;
+}
+ 
+void DS1820::convert_temperature(devices device) {
+    // Convert temperature into scratchpad RAM for all devices at once
+    int delay_time = 750; // Default delay time
+    char resolution;
+    if (device==all_devices)
+        skip_Rom();          // Skip Rom command, will convert for ALL devices
+    else {
+        match_Rom();
+        if (FAMILY_CODE == FAMILY_CODE_DS18B20 ) {
+            resolution = RAM[4] & 0x60;
+            if (resolution == 0x00) // 9 bits
+                delay_time = 94;
+            if (resolution == 0x20) // 10 bits
+                delay_time = 188;
+            if (resolution == 0x40) // 11 bits. Note 12bits uses the 750ms default
+                delay_time = 375;
+        }
+    }
+    onewire_byte_out( 0x44);  // perform temperature conversion
+    if (_parasite_power)
+        _parasitepin = 1;       // Parasite power strong pullup
+    wait_ms(delay_time);
+    if (_parasite_power)
+        _parasitepin = 0;
+}
+ 
+void DS1820::read_RAM() {
+    // This will copy the DS1820's 9 bytes of RAM data
+    // into the objects RAM array. Functions that use
+    // RAM values will automaticly call this procedure.
+    int i;
+    match_Rom();             // Select this device
+    onewire_byte_out( 0xBE);   //Read Scratchpad command
+    for(i=0;i<9;i++) {
+        RAM[i] = onewire_byte_in();
+    }
+}
+ 
+bool DS1820::set_configuration_bits(unsigned int resolution) {
+    bool answer = false;
+    resolution = resolution - 9;
+    if (resolution < 4) {
+        resolution = resolution<<5; // align the bits
+        RAM[4] = (RAM[4] & 0x60) | resolution; // mask out old data, insert new
+        write_scratchpad ((RAM[2]<<8) + RAM[3]);
+//        store_scratchpad (DS1820::this_device); // Need to test if this is required
+        answer = true;
+    }
+    return answer;
+}
+ 
+int DS1820::read_scratchpad() {
+    int answer;
+    read_RAM();
+    answer = (RAM[2]<<8) + RAM[3];
+    return answer;
+}
+ 
+void DS1820::write_scratchpad(int data) {
+    RAM[3] = data;
+    RAM[2] = data>>8;
+    match_Rom();
+    onewire_byte_out(0x4E);   // Copy scratchpad into DS1820 ram memory
+    onewire_byte_out(RAM[2]); // T(H)
+    onewire_byte_out(RAM[3]); // T(L)
+    if ( FAMILY_CODE == FAMILY_CODE_DS18B20 ) {
+        onewire_byte_out(RAM[4]); // Configuration register
+    }
+}
+ 
+void DS1820::store_scratchpad(devices device) {
+    if (device==all_devices)
+        skip_Rom();          // Skip Rom command, will store for ALL devices
+    else
+        match_Rom();
+    onewire_byte_out(0x48);   // Write scratchpad into E2 command
+    if (_parasite_power)
+        _parasitepin=1;
+    wait_ms(10);            // Parasite power strong pullup for 10ms
+    if (_parasite_power)
+        _parasitepin=0;
+}
+ 
+int DS1820::recall_scratchpad(devices device) {
+// This copies the E2 values into the DS1820's memory.
+// If you specify all_devices this will return zero, otherwise
+// it will return the value of the scratchpad memory.
+    int answer=0;
+    if (device==all_devices)
+        skip_Rom();          // Skip Rom command, will recall for ALL devices
+    else
+        match_Rom();
+    onewire_byte_out(0xB8);   // Recall E2 data to scratchpad command
+    wait_ms(10); // not sure I like polling for completion
+                 // it could cause an infinite loop
+    if (device==DS1820::this_device) {
+        read_RAM();
+        answer = read_scratchpad();
+    }
+    return answer;
+}    
+ 
+float DS1820::temperature(char scale) {
+// The data specs state that count_per_degree should be 0x10 (16), I found my devices
+// to have a count_per_degree of 0x4B (75). With the standard resolution of 1/2 deg C
+// this allowed an expanded resolution of 1/150th of a deg C. I wouldn't rely on this
+// being super acurate, but it does allow for a smooth display in the 1/10ths of a
+// deg C or F scales.
+    float answer, remaining_count, count_per_degree;
+    int reading;
+    read_RAM();
+    reading = (RAM[1] << 8) + RAM[0];
+    if (reading & 0x8000) { // negative degrees C
+        reading = 0-((reading ^ 0xffff) + 1); // 2's comp then convert to signed int
+    }
+    answer = reading +0.0; // convert to floating point
+    if ( FAMILY_CODE == FAMILY_CODE_DS18B20 ) {
+        answer = answer / 8.0;
+    }
+    else {
+        remaining_count = RAM[6];
+        count_per_degree = RAM[7];
+        answer = answer - 0.25 + (count_per_degree - remaining_count) / count_per_degree;
+    }
+    if (scale=='C' or scale=='c')
+        answer = answer / 2.0;
+    else
+        // Convert to deg F
+        answer = answer * 9.0 / 10.0 + 32.0;
+    return answer;
+}
+ 
+bool DS1820::read_power_supply(devices device) {
+// This will return true if the device (or all devices) are Vcc powered
+// This will return false if the device (or ANY device) is parasite powered
+    if (device==all_devices)
+        skip_Rom();          // Skip Rom command, will poll for any device using parasite power
+    else
+        match_Rom();
+    onewire_byte_out(0xB4);   // Read power supply command
+    return onewire_bit_in();
+}
\ No newline at end of file
diff -r ee820a991b95 -r cf4f0ea711a7 DS1820.h
--- a/DS1820.h	Thu Dec 15 19:07:36 2011 +0000
+++ b/DS1820.h	Fri Jun 17 12:38:22 2016 +0000
@@ -15,7 +15,7 @@
  * 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,
+ * 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.
  */
@@ -30,7 +30,7 @@
 // Global variables shared between all DS1820 objects
 //bool DS1820_done_flag;
 //int  DS1820_last_descrepancy;
-//char DS1820_search_ROM[8];
+//char DS1820_search_RomM[8];
 
 /** DS1820 Dallas 1-Wire Temperature Probe
  *
@@ -53,15 +53,15 @@
  *     for (i = 0; i < MAX_PROBES; i++)
  *         probe[i] = new DS1820(p27);
  *     // Initialize global state variables
- *     probe[0]->search_ROM_setup();
+ *     probe[0]->search_RomMM_setup();
  *     // Loop to find all devices on the data line
- *     while (probe[devices_found]->search_ROM() and devices_found<MAX_PROBES-1)
+ *     while (probe[devices_found]->search_RomM() and devices_found<MAX_PROBES-1)
  *         devices_found++;
- *     // If maximum number of probes are found, 
+ *     // If maximum number of probes are found,
  *     // bump the counter to include the last array entry
- *     if (probe[devices_found]->ROM[0] != 0xFF)
+ *     if (probe[devices_found]->RomMMMM[0] != 0xFF)
  *         devices_found++;
- * 
+ *
  *     lcd.cls();
  *     if (devices_found==0)
  *         lcd.printf("No devices found");
@@ -77,12 +77,14 @@
  * }
  * @endcode
  */
- 
-class DS1820 {
+
+class DS1820
+{
 public:
-    enum devices{
+    enum devices {
         this_device,     // command applies to only this device
-        all_devices };   // command applies to all devices
+        all_devices
+    };   // command applies to all devices
 
     /** Create a probe object connected to the specified pins
      *
@@ -98,66 +100,66 @@
      */
     DS1820(PinName data_pin);
 
-    /** ROM is a copy of the internal DS1820's ROM
-      * It is created during the search_ROM() or search_alarm() commands
+    /** RomMMM is a copy of the internal DS1820's Rom
+      * It is created during the search_RomM() or search_alarm() commands
       *
-      * ROM[0] is the Dallas Family Code
-      * ROM[1] thru ROM[6] is the 48-bit unique serial number
-      * ROM[7] is the device CRC
+      * RomMMM[0] is the Dallas Family Code
+      * RomMMM[1] thru RomMMM[6] is the 48-bit unique serial number
+      * RomMMM[7] is the device CRC
       */
-    char ROM[8];
-    #define FAMILY_CODE ROM[0]
-    #define FAMILY_CODE_DS1820 0x10
-    #define FAMILY_CODE_DS18S20 0x10
-    #define FAMILY_CODE_DS18B20 0x28
-    
+    char Rom[8];
+#define FAMILY_CODE Rom[0]
+#define FAMILY_CODE_DS1820 0x10
+#define FAMILY_CODE_DS18S20 0x10
+#define FAMILY_CODE_DS18B20 0x28
+
     /** RAM is a copy of the internal DS1820's RAM
       * It's updated during the read_RAM() command
-      * which is automaticaly called from any function
+      * which is automaticaly called fRom any function
       * using the RAM values.
       */
     char RAM[9];
-    
+
     /* This function copies the DS1820's RAM into the object's
      * RAM[].
      */
     void read_RAM();
 
     /** This routine initializes the global variables used in
-      * the search_ROM() and search_alarm() funtions. It should
+      * the search_Rom() and search_alarm() funtions. It should
       * be called once before looping to find devices.
       */
-    void search_ROM_setup();
+    void search_Rom_setup();
 
     /** This routine will search for an unidentified device
-      * on the bus. It uses the variables in search_ROM_setup
-      * to remember the pervious ROM address found.
+      * on the bus. It uses the variables in search_RomMMMM_setup
+      * to remember the pervious RomMMMM address found.
       * It will return FALSE if there were no new devices
       * discovered on the bus.
       */
-    bool search_ROM();
+    bool search_Rom();
 
     /** This routine will search for an unidentified device
-      * which has the temperature alarm bit set. It uses the 
-      * variables in search_ROM_setup to remember the pervious 
-      * ROM address found. It will return FALSE if there were 
+      * which has the temperature alarm bit set. It uses the
+      * variables in search_RomMMM_setup to remember the pervious
+      * RomMMM address found. It will return FALSE if there were
       * no new devices with alarms discovered on the bus.
       */
     bool search_alarm();
 
-    /** This routine will read the ROM (Family code, serial number
-      * and Checksum) from a dedicated device on the bus.
+    /** This routine will read the RomMMMM (Family code, serial number
+      * and Checksum) fRomM a dedicated device on the bus.
       *
-      * NOTE: This command can only be used when there is only one 
-      *       DS1820 on the bus. If this command is used when there 
-      *       is more than one slave present on the bus, a data 
-      *       collision will occur when all the DS1820s attempt to 
+      * NOTE: This command can only be used when there is only one
+      *       DS1820 on the bus. If this command is used when there
+      *       is more than one slave present on the bus, a data
+      *       collision will occur when all the DS1820s attempt to
       *       respond at the same time.
       */
-    void read_ROM();
+    void read_Rom();
 
     /** This routine will initiate the temperature conversion within
-      * a DS1820. There is a built in 750ms delay to allow the 
+      * a DS1820. There is a built in 750ms delay to allow the
       * conversion to complete.
       *
       * To update all probes on the bus, use a statement such as this:
@@ -178,13 +180,13 @@
       * @returns temperature for that scale
       */
     float temperature(char scale='c');
-    
-    /** This function calculates the ROM checksum and compares it to the
-      * CRC value stored in ROM[7].
+
+    /** This function calculates the Rom checksum and compares it to the
+      * CRC value stored in RomMMM[7].
       *
       * @returns true if the checksum matches, otherwise false.
       */
-    bool ROM_checksum_error();
+    bool Rom_checksum_error();
 
     /** This function calculates the RAM checksum and compares it to the
       * CRC value stored in RAM[8].
@@ -194,39 +196,39 @@
     bool RAM_checksum_error();
 
     /** This function returns the values stored in the temperature
-      * alarm registers. 
+      * alarm registers.
       *
       * @returns a 16 bit integer of TH (upper byte) and TL (lower byte).
       */
     bool set_configuration_bits(unsigned int resolution);
-    
+
     /** This function sets the temperature resolution for the DS18B20
       * in the configuration register.
       *
       * @param a number between 9 and 12 to specify the resolution
       * @returns true if successful
-      */ 
+      */
     int read_scratchpad();
-    
+
     /** This function will store the passed data into the DS1820's RAM.
-      * Note: It does NOT save the data to the EEPROM for retention
+      * Note: It does NOT save the data to the EEPRomMMM for retention
       * during cycling the power off and on.
       *
       * @param a 16 bit integer of TH (upper byte) and TL (lower byte).
-      */ 
+      */
     void write_scratchpad(int data);
-    
-    /** This function will transfer the TH and TL registers from the
-      * DS1820's RAM into the EEPROM.
+
+    /** This function will transfer the TH and TL registers fRomM the
+      * DS1820's RAM into the EEPRomMMMM.
       * Note: There is a built in 10ms delay to allow for the
-      * completion of the EEPROM write cycle.
+      * completion of the EEPRomMMM write cycle.
       *
       * @param allows the fnction to apply to a specific device or
       * to all devices on the 1-Wire bus.
-      */ 
+      */
     void store_scratchpad(devices device=this_device);
 
-    /** This function will copy the stored values from the EEPROM
+    /** This function will copy the stored values fRomMMM the EEPRomM
       * into the DS1820's RAM locations for TH and TL.
       *
       * @param allows the function to apply to a specific device or
@@ -247,9 +249,9 @@
     bool _parasite_power;
     char CRC_byte (char CRC, char byte );
     bool onewire_reset();
-    void match_ROM();
-    void skip_ROM();
-    bool search_ROM_routine(char command);
+    void match_Rom();
+    void skip_Rom();
+    bool search_Rom_routine(char command);
     void onewire_bit_out (bool bit_data);
     void onewire_byte_out(char data);
     bool onewire_bit_in();