8 Commits

Author SHA1 Message Date
formtapez
05c23daa25 BOM 2022-01-13 04:57:13 +01:00
formtapez
c14e12ebba fetched version from zigbee2mqtt-pullrequest 2019-09-02 21:18:36 +02:00
formtapez
d0f9c3b111 added temporarily unreleased converters for ds18b20 update 2019-09-02 20:31:34 +02:00
formtapez
70a2b30716 small fix of string length 2019-09-02 20:23:36 +02:00
formtapez
a33fde68bd Merge pull request #9 from prelude0000/master
Added support for 16 ds18b20 temperature sensors
2019-09-02 20:21:35 +02:00
prelude0000
28eb7e1f1b fixed memory leak coused wrong initialization 2019-09-01 19:24:10 +00:00
formtapez
bdf501f410 removed debouncing for S0-pulse to not loose it on nested interrupts 2019-08-31 02:18:02 +02:00
prelude0000
6eaf9c5c45 Added support for 16 ds18b16 temperature sensors 2019-08-21 18:49:21 +00:00
14 changed files with 11091 additions and 77 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)
@@ -74,5 +74,5 @@ Qty | Value | Package | Parts | URL (exemplary supplier)
1 | Phoenix 1792876 | PTS-3 | X1 | https://uk.farnell.com/phoenix-contact/1792876/terminal-block-wire-to-brd-3pos/dp/2072378
2 | TE 1-2834021-4 | MSC4 | X2, X3 | https://uk.farnell.com/te-connectivity/1-2834021-4/tb-wire-to-board-4pos-26-20awg/dp/2610379
1 | DEBUG | MA05-2 | X4 | https://uk.farnell.com/amphenol-icc-fci/67997-210hlf/connector-header-10pos-2row-2/dp/2886080
1 | PCB | FR4 | all | Use [Gerber files](https://github.com/formtapez/ZigUP/tree/master/Layout/Gerber) or [contact me](mailto:ZigUP@posthub.de) if you need a bare PCB
1 | PCB | FR4 | all | Use [Gerber files](https://github.com/formtapez/ZigUP/tree/master/Layout/Gerber) or contact me if you need a bare PCB

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] = { 24, '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

@@ -17,13 +17,8 @@ __interrupt void IRQ_S0(void)
{
if (P0IFG & (1<<6)) // Interrupt flag for P0.6 (S0)?
{
// debounce
_delay_ms(5);
if (!P0_6) // still pressed?
{
S0++;
UART_String("[INT] S0!");
}
S0++;
UART_String("[INT] S0!");
// Clear interrupt flags
P0IFG &= ~(1<<6); // Clear Interrupt flag for P0.6 (S0)

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

View File

@@ -0,0 +1 @@
These files can be used for [zigbee2mqtt](https://www.zigbee2mqtt.io/) as long as the actual changed are not merged and released there.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff