diff --git a/README.md b/README.md index d799d55..e20fa4b 100755 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ CC2530 based multi-purpose ZigBee Relais, Switch, Sensor and Router * 2 Inputs for switches/buttons: * Input "KEY" directly toggles the relais and outputs a ZigBee message * Input "DIG" only outputs a ZigBee message - So your coordinator can decide if the relais has to be toggled or not. -* Input for digital temperature and humidity sensors (DHT22/AM2302/DS18B20) (Measurements will be reported via ZigBee) +* Input for 16 digital temperature (DS18B20) and 1 humidity sensors (DHT22/AM2302) (Measurements will be reported via ZigBee) * Input for S0-Bus impulses from power-, water- or gas-meters. Count-Value will be reported via ZigBee) * Output for one normal LED or up to 10 WS2812B/Neopixel RGB-LEDs (controllable via ZigBee) * Analog input to measure voltages of up to 32 Volt. (Voltage will be reported via ZigBee) diff --git a/src/ZigUP/Source/ds18b20.c b/src/ZigUP/Source/ds18b20.c index c2fb8ea..fcdc5b1 100755 --- a/src/ZigUP/Source/ds18b20.c +++ b/src/ZigUP/Source/ds18b20.c @@ -6,103 +6,297 @@ #include "ds18b20.h" #include "uart.h" #include "global.h" +#include "hal_mcu.h" + + +#define DS18B20_SKIP_ROM 0xCC +#define DS18B20_CONVERT_T 0x44 +#define DS18B20_MATCH_ROM 0x55 +#define DS18B20_SEARCH_ROM 0XF0 +#define DS18B20_READ_SCRATCHPAD 0xBE +#define DS18B20_WRITE_SCRATCHPAD 0x4E +#define DS18B20_COPY_SCRATCHPAD 0x48 + // Sends one bit to bus -void ds18b20_send(uint8 bit) +void ds18b20_send_bit(uint8 bit, uint8 useInterrupts) { + P0_7 = 1; + if (useInterrupts) + HAL_DISABLE_INTERRUPTS(); P0DIR |= (1<<7); // output P0_7 = 0; - _delay_us(5); - if (bit==1) P0_7 = 1; - _delay_us(80); + if ( bit != 0 ) + _delay_us( 8 ); + else + _delay_us( 80 ); P0_7 = 1; + if (useInterrupts) + HAL_ENABLE_INTERRUPTS(); + if ( bit != 0 ) + _delay_us( 80 ); + else + _delay_us( 2 ); + +// if (bit==1) P0_7 = 1; +// _delay_us(100); +// P0_7 = 1; } + // Reads one bit from bus -uint8 ds18b20_read(void) +uint8 ds18b20_read_bit(uint8 useInterrupts) { + uint8 i; + + + P0_7 = 1; + if (useInterrupts) + HAL_DISABLE_INTERRUPTS(); P0DIR |= (1<<7); // output P0_7 = 0; _delay_us(2); - P0_7 = 1; - _delay_us(15); +// P0_7 = 1; +// _delay_us(15); P0DIR &= ~(1<<7); // input - return P0_7; + _delay_us( 5 ); + i = P0_7; + if (useInterrupts) + HAL_ENABLE_INTERRUPTS(); + _delay_us( 60 ); + return i; } + // Sends one byte to bus -void ds18b20_send_byte(int8 data) +void ds18b20_send_byte(int8 data, uint8 useInterrupts) { uint8 i,x; for(i=0;i<8;i++) { x = data>>i; x &= 0x01; - ds18b20_send(x); + ds18b20_send_bit(x, useInterrupts); } - _delay_us(100); + //_delay_us(100); } + // Reads one byte from bus -uint8 ds18b20_read_byte(void) +uint8 ds18b20_read_byte(uint8 useInterrupts) { uint8 i; uint8 data = 0; for (i=0;i<8;i++) { - if(ds18b20_read()) data|=0x01< return false { - ds18b20_send_byte(0xCC); - ds18b20_send_byte(0x44); - _delay_ms(750); - ds18b20_RST_PULSE(); - ds18b20_send_byte(0xCC); - ds18b20_send_byte(0xBE); - temp1=ds18b20_read_byte(); - temp2=ds18b20_read_byte(); - ds18b20_RST_PULSE(); - - if (temp1 == 0xff && temp2 == 0xff) - { - UART_String("DS18B20: No sensor found."); - return 0; - } - - // neg. temp - if (temp2 & b00001000) EXT_Temperature = ((uint16)temp1 | (uint16)(temp2 & b00000111) << 8) / 16.0 - 128.0; - // pos. temp - else EXT_Temperature = ((uint16)temp1 | (uint16)(temp2 & b00000111) << 8) / 16.0; - - sprintf(buffer, "DS18B20: %.2f °C (0x%02X 0x%02X)\n", EXT_Temperature, temp1, temp2); - UART_String(buffer); - return 1; + ds18b20_lastDiscrep = 0; // reset the search + return FALSE; } + ds18b20_send_byte(0xF0, 0); // send SearchROM command + do + // for all eight bytes + { + x = 0; + if(ds18b20_read_bit(0)==1) + x = 2; + _delay_us(15); + if(ds18b20_read_bit(0)==1) + x |= 1; // and its complement + if(x ==3) // there are no devices on the 1-Wire + break; + else + { + if(x>0) // all devices coupled have 0 or 1 + g = x>>1; // bit write value for search + else + { + // if this discrepancy is before the last + // discrepancy on a previous Next then pick + // the same as last time + if(m0); + else // if equal to last pick 1 + g = (m==ds18b20_lastDiscrep); // if not then pick 0 + // if 0 was picked then record + // position with mask k + if (g==0) + discrepMarker = m; + } + if(g==1) // isolate bit in ROM[n] with mask k + ds18b20_ROM[n] |= k; + else + ds18b20_ROM[n] &= ~k; + ds18b20_send_bit(g, 0); // ROM search write + m++; // increment bit counter m + k = k<<1; // and shift the bit mask k + if(k==0) // if the mask is 0 then go to new ROM + { // byte n and reset mask + ds18b20_ow_crc(ds18b20_ROM[n]); // accumulate the CRC + n++; k++; + } + } + }while(n<8); //loop until through all ROM bytes 0-7 + + if(m<65||ds18b20_dowcrc) // if search was unsuccessful then + ds18b20_lastDiscrep=0; // reset the last discrepancy to 0 else { - UART_String("DS18B20: Fail."); - return 0; + // search was successful, so set lastDiscrep, + // lastOne, nxt + ds18b20_lastDiscrep = discrepMarker; + ds18b20_doneFlag = (ds18b20_lastDiscrep==0); + nxt = TRUE; // indicates search is not complete yet, more + // parts remain + } + return nxt; +} + + +// FIRST +// The First function resets the current state of a ROM search and calls +// Next to find the first device on the 1-Wire bus. +// +uint8 ds18b20_First(void) +{ + ds18b20_lastDiscrep = 0; // reset the rom search last discrepancy global + ds18b20_doneFlag = FALSE; + return ds18b20_Next(); // call Next and return its return value +} + + +uint8 ds18b20_find_devices(void) +{ + unsigned char m; + ds18b20_numROMs=0; + char buffer[100]; + + if(!ds18b20_RST_PULSE()) //Begins when a presence is detected + { + if(ds18b20_First()) //Begins when at least one part is found + { + do + { + for(m=0;m<8;m++) + { + ds18b20_FoundROM[ds18b20_numROMs][m] = ds18b20_ROM[m]; //Identifies ROM + } + sprintf(buffer, "Sensor %d ROM CODE = %02X%02X%02X%02X%02X%02X%02X%02X", ds18b20_numROMs, + ds18b20_FoundROM[ds18b20_numROMs][7],ds18b20_FoundROM[ds18b20_numROMs][6],ds18b20_FoundROM[ds18b20_numROMs][5],ds18b20_FoundROM[ds18b20_numROMs][4], + ds18b20_FoundROM[ds18b20_numROMs][3],ds18b20_FoundROM[ds18b20_numROMs][2],ds18b20_FoundROM[ds18b20_numROMs][1],ds18b20_FoundROM[ds18b20_numROMs][0]); + UART_String(buffer); + ds18b20_numROMs++; + }while (ds18b20_Next()&&(ds18b20_numROMs +#include #include "hal_flash.h" #include "onboard.h" #include "delay.h" @@ -49,7 +51,38 @@ void Measure_QuickStuff(void) void Measure_Sensor(void) { + char buffer[100]; + uint8 i; + // make new measurement depending of autodetected sensor type - if (TEMP_SENSOR == 1) DHT22_Measure(); - else if (TEMP_SENSOR == 2) ds18b20_get_temp(); + if (TEMP_SENSOR == -1) + DHT22_Measure(); + else if (TEMP_SENSOR != 0) + { + ds18b20_start_conversion(); + + i = ds18b20_current; + + EXT_Temperatures[i] = ds18b20_get_sensor_temperature(i); + sprintf(buffer, "%02X%02X%02X%02X%02X%02X%02X%02X: %.2f °C", + ds18b20_FoundROM[i][7],ds18b20_FoundROM[i][6],ds18b20_FoundROM[i][5],ds18b20_FoundROM[i][4], + ds18b20_FoundROM[i][3],ds18b20_FoundROM[i][2],ds18b20_FoundROM[i][1],ds18b20_FoundROM[i][0], + EXT_Temperatures[i]); + if(i==0) + EXT_Temperature = EXT_Temperatures[0]; + UART_String(buffer); + + sprintf(EXT_Temperature_string, "\x01%02X%02X%02X%02X%02X%02X%02X%02X:%.2f", + ds18b20_FoundROM[i][7],ds18b20_FoundROM[i][6],ds18b20_FoundROM[i][5],ds18b20_FoundROM[i][4], + ds18b20_FoundROM[i][3],ds18b20_FoundROM[i][2],ds18b20_FoundROM[i][1],ds18b20_FoundROM[i][0], + EXT_Temperatures[i]); + EXT_Temperature_string[0] = strlen(EXT_Temperature_string) - 1; + + + ds18b20_current++; + + if(ds18b20_current >= ds18b20_numROMs) + ds18b20_current = 0; + + } } diff --git a/src/ZigUP/Source/zcl_zigup.c b/src/ZigUP/Source/zcl_zigup.c index 6301b89..0b49953 100755 --- a/src/ZigUP/Source/zcl_zigup.c +++ b/src/ZigUP/Source/zcl_zigup.c @@ -42,7 +42,7 @@ devStates_t zclZigUP_NwkState = DEV_INIT; void zclZigUP_Reporting(uint16 REPORT_REASON) { - const uint8 NUM_ATTRIBUTES = 8; + const uint8 NUM_ATTRIBUTES = 9; // send report zclReportCmd_t *pReportCmd; @@ -83,6 +83,11 @@ void zclZigUP_Reporting(uint16 REPORT_REASON) pReportCmd->attrList[7].attrID = ATTRID_REPORT_REASON; pReportCmd->attrList[7].dataType = ZCL_DATATYPE_UINT16; pReportCmd->attrList[7].attrData = (void *)(&REPORT_REASON); + + pReportCmd->attrList[8].attrID = ATTRID_EXT_TEMPS; + pReportCmd->attrList[8].dataType = ZCL_DATATYPE_CHAR_STR; + pReportCmd->attrList[8].attrData = (void *)(&EXT_Temperature_string); + zclZigUP_DstAddr.addrMode = (afAddrMode_t)Addr16Bit; zclZigUP_DstAddr.addr.shortAddr = 0; @@ -309,20 +314,26 @@ void zclZigUP_Init( byte task_id ) ADC_Voltage = *(float*)&float_NaN; CPU_Temperature = *(float*)&float_NaN; + char buffer[100]; + // autodetecting sensor type if (DHT22_Measure()) { - TEMP_SENSOR = 1; + TEMP_SENSOR = -1; UART_String("Sensor type DHT22 detected."); } - else if (ds18b20_get_temp()) + else if(TEMP_SENSOR = ds18b20_find_devices()) { - TEMP_SENSOR = 2; - UART_String("Sensor type DS18B20 detected."); + sprintf(buffer, "Found %d ds18b20 sensors", TEMP_SENSOR); + UART_String(buffer); + } + else + { + sprintf(buffer, "No sensor detected. code: %d", TEMP_SENSOR); + UART_String(buffer); } - else UART_String("No sensor detected."); - // start measurement task for reporting of values +// start measurement task for reporting of values osal_start_reload_timer( zclZigUP_TaskID, ZIGUP_REPORTING_EVT, ZIGUP_REPORTING_INTERVAL ); UART_String("Init done."); diff --git a/src/ZigUP/Source/zcl_zigup.h b/src/ZigUP/Source/zcl_zigup.h index e72f46b..22b1f4d 100755 --- a/src/ZigUP/Source/zcl_zigup.h +++ b/src/ZigUP/Source/zcl_zigup.h @@ -28,7 +28,8 @@ extern "C" #define ATTRID_ADC_VOLT 41365 #define ATTRID_DIG_INPUT 41366 #define ATTRID_REPORT_REASON 41367 - +#define ATTRID_EXT_TEMPS 41368 + extern SimpleDescriptionFormat_t zclZigUP_SimpleDesc[]; extern CONST zclCommandRec_t zclZigUP_Cmds[]; diff --git a/src/ZigUP/Source/zcl_zigup_data.c b/src/ZigUP/Source/zcl_zigup_data.c index 1dc7162..2f50acd 100755 --- a/src/ZigUP/Source/zcl_zigup_data.c +++ b/src/ZigUP/Source/zcl_zigup_data.c @@ -33,7 +33,7 @@ const uint8 zclZigUP_HWRevision = ZIGUP_HWVERSION; const uint8 zclZigUP_ZCLVersion = ZIGUP_ZCLVERSION; const uint8 zclZigUP_ManufacturerName[] = { 9, 'f','o','r','m','t','a','p','e','z' }; const uint8 zclZigUP_ModelId[] = { 5, 'Z','i','g','U','P' }; -const uint8 zclZigUP_DateCode[] = { 16, '2','0','1','9','0','6','2','2',' ',' ',' ',' ',' ',' ',' ',' ' }; +const uint8 zclZigUP_DateCode[] = { 16, '2','0','1','9','0','8','2','1',' ',' ',' ',' ',' ',' ',' ',' ' }; const uint8 zclZigUP_PowerSource = POWER_SOURCE_MAINS_1_PHASE; uint8 zclZigUP_LocationDescription[17] = { 16, ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };