First commit

This commit is contained in:
Nigreon 2025-12-30 22:38:10 +01:00
commit adb0fe2037
5 changed files with 289 additions and 0 deletions

12
fuses.orig Normal file
View File

@ -0,0 +1,12 @@
junk: :09000000
fuse0: 00
fuse1: 00
fuse2: 02
fuse3: FF
fuse4: 00
fuse5: F6
fuse6: 07
fuse7: 00
fuse8: 00
junk: F9
more junk: :00000001FF

24
platformio.ini Normal file
View File

@ -0,0 +1,24 @@
[platformio]
default_envs = tiny1614
[env:tiny1614]
platform = atmelmegaavr
platform_packages = framework-arduino-megaavr-megatinycore @ https://github.com/SpenceKonde/megaTinyCore/
board = ATtiny1614
framework = arduino
board_build.f_cpu = 4000000L
board_hardware.bod = disabled
lib_deps =
robtillaart/SHT4x
upload_protocol = serialupdi
#upload_flags =
# -P$UPLOAD_PORT
# -b$UPLOAD_SPEED
# -V
targets = upload, monitor
#targets = upload
#upload_speed = 19200
monitor_filters = time
upload_port = /dev/ttyACM0
monitor_speed = 9600
monitor_port = /dev/ttyUSB0

1
src/inFactoryTransmit.h Normal file
View File

@ -0,0 +1 @@
void sendInfactory(int pin, uint8_t id, uint8_t channel, bool batteryOK, bool button, uint8_t humidity, float temperature);

97
src/inFactoryTransmit.ino Normal file
View File

@ -0,0 +1,97 @@
uint8_t msg[5];
uint8_t pin_tx;
uint8_t crc4(uint8_t const message[], unsigned nBytes, uint8_t polynomial, uint8_t init)
{
unsigned remainder = init << 4; // LSBs are unused
unsigned poly = polynomial << 4;
unsigned bit;
while (nBytes--) {
remainder ^= *message++;
for (bit = 0; bit < 8; bit++) {
if (remainder & 0x80) {
remainder = (remainder << 1) ^ poly;
} else {
remainder = (remainder << 1);
}
}
}
return remainder >> 4 & 0x0f; // discard the LSBs
}
void sendInfactory(int pin, uint8_t id, uint8_t channel, bool batteryOK, bool button, uint8_t humidity, float temperature) {
pin_tx = pin;
// put your setup code here, to run once:
msg[0] = id;
msg[4] = channel + ((humidity%10) << 4 );
msg[3] = humidity/10;
//int binTemp = ((temperature * 9./5) + 32 + 90)*10;
int binTemp = (temperature+90)*10;
msg[3] += (binTemp & 0x0F) << 4;
msg[2] = binTemp >> 4;
//msg[1] = batteryOK << 2;
msg[1] = button << 3;
msg[1] = msg[1] | (!batteryOK << 2);
msg[1] = (msg[1] & 0x0F) | (msg[4] & 0x0F) << 4;
// crc4() only works with full bytes
uint8_t crc = crc4(msg, 4, 0x13, 0); // Koopmann 0x9, CCITT-4; FP-4; ITU-T G.704
crc ^= msg[4] >> 4; // last nibble is only XORed
msg[1] = (msg[1] & 0x0F) | (crc & 0x0F) << 4;
//for (int i=0; i<=4; i++){
// Serial.print(msg[i],HEX);
// Serial.print(" ");
//}
sendRF();
}
void sendRF()
{
/*low long 4000
low short 1800
high short 700
*/
noInterrupts();
//for (int n=0; n<6; n++)
for (int n=0; n<2; n++)
{
for (int i=0; i<8; i++){
digitalWrite(pin_tx, !(i%2));
delayMicroseconds(1000);
}
digitalWrite(pin_tx, HIGH);
delayMicroseconds(550);
digitalWrite(pin_tx, LOW);
delayMicroseconds(8000);
for (int i = 0; i<5; i++) {
for (int b = 7; b>=0; b--) {
digitalWrite(pin_tx, HIGH);
//delayMicroseconds(700);
delayMicroseconds(550);
digitalWrite(pin_tx, LOW);
if (bitRead(msg[i], b)){
delayMicroseconds(4000);
}
else{
//delayMicroseconds(1800);
delayMicroseconds(2000);
}
}
}
digitalWrite(pin_tx, HIGH);
delayMicroseconds(550);
digitalWrite(pin_tx, LOW);
delayMicroseconds(16000);
}
interrupts();
}

155
src/main.ino Normal file
View File

@ -0,0 +1,155 @@
#include <avr/sleep.h>
#include "Wire.h"
#include "SHT4x.h"
#include "inFactoryTransmit.h"
#define PIN_TX 3
#define CHANNEL 1
#define ID 11
SHT4x sht;
bool butval = false;
bool batval = true;
int8_t sendfromstart = 0;
int8_t sendcountbat = 0;
void RTC_init(void)
{
/* Initialize RTC: */
while (RTC.STATUS > 0)
{
; /* Wait for all register to be synchronized */
}
RTC.CLKSEL = RTC_CLKSEL_INT32K_gc; /* 32.768kHz Internal Ultra-Low-Power Oscillator (OSCULP32K) */
RTC.PITINTCTRL = RTC_PI_bm; /* PIT Interrupt: enabled */
RTC.PITCTRLA = RTC_PERIOD_CYC16384_gc /* RTC Clock Cycles 16384, resulting in 32.768kHz/16384 = 2Hz */
| RTC_PITEN_bm; /* Enable PIT counter: enabled */
}
ISR(RTC_PIT_vect)
{
RTC.PITINTFLAGS = RTC_PI_bm; /* Clear interrupt flag by writing '1' (required) */
}
void sleepNSeconds(uint16_t val) {
// Serial.flush();
// first cycle may not be full cycle
//disableAllPeripherals(); // all off
for (uint16_t i = 0; i < (val*2) ; i++) {
//diagnosticPinLow(); // set low to show sleeping
sleep_cpu(); // put MCU to sleep
//diagnosticPinHigh(); // set high to show awake
}
// now awake, sleep cycles complete, continue on
//initSerialGPIO(); // initialize serial and GPIO
}
//returns Vdd volts*100 (3.21v = return 321)
uint16_t readVdd() {
uint16_t ret;
//ADC0.CTRLA |= ADC_ENABLE_bm;
//adc0 VREF = 1v1
VREF.CTRLA = (VREF.CTRLA & ~VREF_ADC0REFSEL_gm) | VREF_ADC0REFSEL_1V1_gc;
ADC0.CTRLB = ADC_SAMPNUM_ACC64_gc; //64 samples
ADC0.CTRLC = ADC_REFSEL_VDDREF_gc | ADC_PRESC_DIV16_gc | ADC_SAMPCAP_bm;
ADC0.CTRLD = ADC_INITDLY_DLY64_gc;
ADC0.MUXPOS = ADC_MUXPOS_INTREF_gc;
ADC0.CTRLA = 1; //enable adc
ADC0.COMMAND = 1; //start
while( ADC0.COMMAND ){} //wait
//Vdd*100 = 1023*1.1*100*64/res (64 samples, so *64 also)
ret = (1023*1.1*100ul*64) / ADC0.RES;
ADC0.CTRLA &= ~ADC_ENABLE_bm;
//Serial.print("Vdd:");
//Serial.println(ret);
return ret;
}
bool batok() {
return (readVdd()-240)/0.4 < 20 ? false : true;
}
void setup(void)
{
RTC_init(); /* Initialize the RTC timer */
set_sleep_mode(SLEEP_MODE_PWR_DOWN); /* Set sleep mode to POWER DOWN mode */
sleep_enable(); /* Enable sleep mode, but not going to sleep yet */
ADC0.CTRLA &= ~ADC_ENABLE_bm; // Disable ADC
TCA0.SPLIT.CTRLA = 0; // Disable Timers
pinMode(PIN_PA0, INPUT_PULLUP);
pinMode(PIN_PA1, INPUT_PULLUP);
pinMode(PIN_PA2, INPUT_PULLUP);
pinMode(PIN_PA3, INPUT_PULLUP);
pinMode(PIN_PA4, INPUT_PULLUP);
pinMode(PIN_PA5, INPUT_PULLUP);
pinMode(PIN_PA6, INPUT_PULLUP);
USART0.CTRLB &= ~USART_RXEN_bm & ~USART_TXEN_bm; // disable USART
pinMode(PIN_PB2, INPUT_PULLUP);
pinMode(PIN_PB3, INPUT_PULLUP);
//Serial.begin(9600);
//Serial.println("Hello ATTiny1614");
pinMode(PIN_TX, OUTPUT);
batval = batok();
Wire.begin();
sht.begin();
sht.setHeatProtection(false);
sht.read();
}
void loop(void)
{
//readVdd();
if(sht.read() == true) {
float temperature = sht.getFahrenheit();
//float temperature = sht.getTemperature();
uint8_t humidity = (uint8_t) sht.getHumidity();
//Serial.print("Temperature ");
//Serial.println(sht.getTemperature(), 1);
//Serial.print("Humidity ");
//Serial.println(humidity, 1);
if(sendfromstart == 10)
{
butval = false;
sendfromstart = -1;
sendcountbat = 0;
} else if(sendfromstart >= 0)
{
butval = true;
sendfromstart++;
}
if(sendcountbat == 2)
//if(sendcountbat == 60)
{
sendcountbat = 0;
batval = batok();
} else {
sendcountbat++;
}
sendInfactory(PIN_TX, ID, CHANNEL, batval, butval, humidity, temperature);
} else {
//Serial.print("SHTError ");
//Serial.println(sht.getError());
}
if(butval == true) {
//Serial.println("Sleep Short");
sleepNSeconds(25+random(0,10));
} else {
//Serial.println("Sleep Long");
sleepNSeconds(55+random(0,10));
}
//delay(5000);
}