Merge pull request #9 from prelude0000/master

Added support for 16 ds18b20 temperature sensors
This commit is contained in:
formtapez
2019-09-02 20:21:35 +02:00
committed by GitHub
9 changed files with 357 additions and 69 deletions

View File

@@ -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)

View File

@@ -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<<i;
_delay_us(15);
if(ds18b20_read_bit(useInterrupts)) data|=0x01<<i;
//_delay_us(25);
}
return(data);
}
// Sends reset pulse
uint8 ds18b20_RST_PULSE(void)
{
P0DIR |= (1<<7); // output
uint8 i;
P0_7 = 0;
_delay_us(500);
P0_7 = 1;
P0DIR |= (1<<7); // output
_delay_us(600);
P0DIR &= ~(1<<7); // input
_delay_us(500);
return P0_7;
_delay_us(70);
i = P0_7;
_delay_us(200);
P0_7 = 1;
P0DIR |= (1<<7); // output
_delay_us(600);
return i;
}
// Returns temperature from sensor
uint8 ds18b20_get_temp(void)
//////////////////////////////////////////////////////////////////////////////
// ONE WIRE CRC
//
uint8 ds18b20_ow_crc( uint8 x)
{
char buffer[100];
uint8 temp1, temp2;
if(ds18b20_RST_PULSE())
ds18b20_dowcrc = ds18b20_dscrc_table[ds18b20_dowcrc^x];
return ds18b20_dowcrc;
}
// NEXT
// The Next function searches for the next device on the 1-Wire bus. If
// there are no more devices on the 1-Wire then false is returned.
//
uint8 ds18b20_Next(void)
{
uint8 m = 1; // ROM Bit index
uint8 n = 0; // ROM Byte index
uint8 k = 1; // bit mask
uint8 x = 0;
uint8 discrepMarker = 0; // discrepancy marker
uint8 g; // Output bit
uint8 nxt; // return value
int flag;
nxt = FALSE; // set the next flag to false
ds18b20_dowcrc = 0; // reset the dowcrc
flag = ds18b20_RST_PULSE(); // reset the 1-Wire
if(flag|| ds18b20_doneFlag) // no parts -> 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 <20>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(m<ds18b20_lastDiscrep)
g = ((ds18b20_ROM[n]&k)>0);
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<ds18b20_MAX_DEVICES+1)); //Continues until no additional devices are found
}
}
return ds18b20_numROMs;
}
void ds18b20_start_conversion(void)
{
if(!ds18b20_RST_PULSE())
{
ds18b20_send_byte(DS18B20_SKIP_ROM, 1);
ds18b20_send_byte(DS18B20_CONVERT_T, 1);
_delay_ms(750);
}
}
void ds18b20_SelectSensor(uint8 ID)
{
uint8 i;
if(!ds18b20_RST_PULSE())
{
ds18b20_send_byte(DS18B20_MATCH_ROM, 1); // DS18B20_MATCH_ROM
for(i=0;i<8;i++)
{
ds18b20_send_byte(ds18b20_FoundROM[ID][i], 1); //send ROM code
}
}
}
float ds18b20_get_sensor_temperature(uint8 deviceId)
{
uint8 temp1, temp2;
float temperature = -999.99;
//EXT_Temperature = -999.99;
ds18b20_SelectSensor(deviceId);
ds18b20_send_byte(DS18B20_READ_SCRATCHPAD, 1);
temp1=ds18b20_read_byte(1);
temp2=ds18b20_read_byte(1);
ds18b20_RST_PULSE();
if (temp1 == 0xff && temp2 == 0xff)
{
// cannot find sensor
return temperature;
//return EXT_Temperature;
}
// neg. temp
if (temp2 & b00001000) temperature = ((uint16)temp1 | (uint16)(temp2 & b00000111) << 8) / 16.0 - 128.0;
// pos. temp
else temperature = ((uint16)temp1 | (uint16)(temp2 & b00000111) << 8) / 16.0;
return temperature;
}

View File

@@ -1,6 +1,12 @@
void ds18b20_send(uint8 bit);
uint8 ds18b20_read(void);
void ds18b20_send_byte(int8 data);
uint8 ds18b20_read_byte(void);
void ds18b20_send_bit(uint8 bit, uint8 useInterrupts);
uint8 ds18b20_read_bit(uint8 useInterrupts);
void ds18b20_send_byte(int8 data, uint8 useInterrupts);
uint8 ds18b20_read_byte(uint8 useInterrupts);
uint8 ds18b20_RST_PULSE(void);
uint8 ds18b20_get_temp(void);
uint8 ds18b20_find_devices(void);
uint8 ds18b20_Next(void);
uint8 ds18b20_First(void);
uint8 ds18b20_ow_crc( uint8 x);
void ds18b20_start_conversion(void);
float ds18b20_get_sensor_temperature(uint8);
void ds18b20_SelectSensor(uint8);

View File

@@ -1,4 +1,5 @@
#include "ZComDef.h"
#include "global.h"
uint32 float_NaN = 0x7F800001;
@@ -15,4 +16,31 @@ volatile uint32 S0=0;
volatile uint8 STATE_LIGHT=0;
volatile uint8 STATE_LED=0;
uint8 TEMP_SENSOR=0;
int8 TEMP_SENSOR=0;
uint8 ds18b20_ROM[8]; // ROM Bit
uint8 ds18b20_lastDiscrep = 0; // last discrepancy
uint8 ds18b20_doneFlag = 0; // Done flag
uint8 ds18b20_FoundROM[ds18b20_MAX_DEVICES][8]; // table of found ROM codes
uint8 ds18b20_numROMs;
uint8 ds18b20_dowcrc;
uint8 ds18b20_current;
volatile uint8 ds18b20_dscrc_table[] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
char EXT_Temperature_string[1 + 8*2 + 1 + 7 + 1] = { 25, '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', ':', '-', '9', '9', '9', '.', '9', '9', 0 };
float EXT_Temperatures[ds18b20_MAX_DEVICES];

View File

@@ -8,6 +8,7 @@ extern float ADC_Voltage;
extern float CPU_Temperature;
extern uint16 DIG_IN;
extern byte zclZigUP_TaskID;
extern uint16 zclZigUPSeqNum;
@@ -15,8 +16,22 @@ extern volatile uint32 S0;
extern volatile uint8 STATE_LIGHT;
extern volatile uint8 STATE_LED;
extern uint8 TEMP_SENSOR;
extern int8 TEMP_SENSOR;
#define REPORT_REASON_TIMER 0
#define REPORT_REASON_KEY 1
#define REPORT_REASON_DIGIN 2
#define ds18b20_MAX_DEVICES 16
extern uint8 ds18b20_ROM[8]; // ROM Bit
extern uint8 ds18b20_lastDiscrep; // last discrepancy
extern uint8 ds18b20_doneFlag; // Done flag
extern uint8 ds18b20_FoundROM[ds18b20_MAX_DEVICES][8]; // table of found ROM codes
extern uint8 ds18b20_numROMs;
extern uint8 ds18b20_dowcrc;
extern volatile uint8 ds18b20_dscrc_table[];
extern char EXT_Temperature_string[1 + 8*2 + 1 + 7 + 1];
extern float EXT_Temperatures[ds18b20_MAX_DEVICES];
extern uint8 ds18b20_current;

View File

@@ -1,3 +1,5 @@
#include <stdio.h>
#include <string.h>
#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 <20>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;
}
}

View File

@@ -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.");

View File

@@ -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[];

View File

@@ -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, ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };