Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Firmware/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build*
31 changes: 31 additions & 0 deletions Firmware/Zero2Go-Omini/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
FROM ubuntu:19.10

RUN apt-get -yq update \
&& apt-get -yq --no-install-suggests --no-install-recommends install \
wget \
git \
avrdude \
python-serial \
xz-utils \
ca-certificates \
make \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN wget https://downloads.arduino.cc/arduino-1.8.10-linux64.tar.xz \
&& tar xf *.tar.xz -C /opt \
&& rm *.tar.xz

RUN git clone https://github.com/sudar/Arduino-Makefile -b 1.5.2 /opt/arduino-mk

RUN git clone https://github.com/SpenceKonde/ATTinyCore.git -b v1.1.4 /opt/ATTinyCore

RUN git clone https://github.com/orangkucing/WireS.git /opt/WireS \
&& cd /opt/WireS \
&& git reset --hard 776ffa23b6b9b8ae17b21e10357e22b09e7e9510

RUN git clone https://github.com/orangkucing/analogComp /opt/analogComp

WORKDIR /src

CMD ["make"]
16 changes: 16 additions & 0 deletions Firmware/Zero2Go-Omini/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
TARGET = Zero2Go-Omini.ino
ARDUINO_DIR = /opt/arduino-1.8.10
USER_LIB_PATH = /opt

# Programmer type:
ISP_PROG = usbasp

# https://github.com/SpenceKonde/ATTinyCore (1.5+)
ALTERNATE_CORE = ATTinyCore
ALTERNATE_CORE_PATH = /opt/ATTinyCore
BOARD_TAG = attinyx41
BOARD_SUB = 841
F_CPU = 8000000L

# Path to the Arduino Makefile
include /opt/arduino-mk/Arduino.mk
87 changes: 83 additions & 4 deletions Firmware/Zero2Go-Omini/Zero2Go-Omini.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <core_timers.h>
#include <analogComp.h>
#include <avr/sleep.h>
#include <util/delay.h>
#include <WireS.h>
#include <EEPROM.h>

Expand Down Expand Up @@ -38,8 +39,9 @@
#define I2C_CONF_BULK_ALWAYS_ON 13 // always enable bulk converter: 1=yes, 0=no
#define I2C_CONF_POWER_CUT_DELAY 14 // the delay (x10) before power cut: default=50 (5 sec)
#define I2C_CONF_RECOVERY_VOLTAGE 15 // voltage (x10) that triggers recovery, 255=disabled
#define I2C_CONF_WATCHDOG_TIMEOUT 16 // set watchdog timeout, reset watchdog, 0=disabled

#define I2C_REG_COUNT 16 // number of I2C registers
#define I2C_REG_COUNT 17 // number of I2C registers

volatile byte i2cReg[I2C_REG_COUNT];

Expand All @@ -63,6 +65,28 @@ volatile unsigned long buttonStateChangeTime = 0;

volatile unsigned long voltageQueryTime = 0;

volatile int watchdogCounter = 0;

void timer1_enable();
void timer2_enable();
void cutPower();
void powerOn();
void redLightOn();
void suggestShutdown();
void redLightOff();
void initializeRegisters();
void updateRegister(int index, byte value);
float getVoltage(int pin);
int getIntegerPart(float v);
int getDecimalPart(float v);
unsigned int getPowerCutPreloadTimer();
void receiveEvent(int count);
boolean addressEvent(uint16_t slaveAddress, uint8_t startCount);
void requestEvent();
void comparatorStatusChanged();
void sleep();
void resetWatchdog();

void setup() {

// initialize pin states and make sure power is cut
Expand Down Expand Up @@ -106,6 +130,11 @@ void setup() {
// enable Timer1
timer1_enable();

// enable watchdog
if (i2cReg[I2C_CONF_WATCHDOG_TIMEOUT]) {
resetWatchdog();
}

// enable comparator
analogComparator.setOn(INTERNAL_REFERENCE, AIN1);
analogComparator.enableInterrupt(comparatorStatusChanged, CHANGE);
Expand All @@ -121,6 +150,7 @@ void setup() {
} else {
sleep(); // sleep and wait for button action
}

}


Expand Down Expand Up @@ -175,6 +205,8 @@ void initializeRegisters() {
i2cReg[I2C_CONF_POWER_CUT_DELAY] = 50;
i2cReg[I2C_CONF_RECOVERY_VOLTAGE] = 255;

i2cReg[I2C_CONF_WATCHDOG_TIMEOUT] = 0;

// make sure product name is stored
EEPROM.update(0, 'Z');
EEPROM.update(1, 'e');
Expand Down Expand Up @@ -238,9 +270,14 @@ void timer1_disable() {
bitClear(TIMSK1, TOIE1);
}

void timer2_disable() {
// disable Timer2 overflow interrupt:
bitClear(TIMSK2, TOIE2);
}

void sleep() {
timer1_disable(); // disable Timer1
timer2_disable();
ADCSRA &= ~_BV(ADEN); // ADC off
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // power-down mode
watchdog_enable(); // enable watchdog
Expand Down Expand Up @@ -466,6 +503,22 @@ ISR (TIM1_OVF_vect) {
}


// timer2 overflow interrupt routine
ISR (TIM2_OVF_vect) {
// overflow in 8s
TCNT2 = 3035;
watchdogCounter++;
// minimum watchdog timeout is 1m20s
if (watchdogCounter >= (i2cReg[I2C_CONF_WATCHDOG_TIMEOUT] + 9)){
// watchdog timeout, trigger a reboot
watchdogCounter = 0;
cutPower();
_delay_ms (5000);
powerOn();
}
}


// analog comparator interrupt routine
void comparatorStatusChanged() {
bulkOrBoost = ((ACSR0A & (1<<ACO)) == 0);
Expand All @@ -475,14 +528,40 @@ void comparatorStatusChanged() {
}
}

void resetWatchdog() {
watchdogCounter = 0;
// overflow in 8s
TCNT2 = 3035;

// initialize Timer2
TCCR2A = 0; // set entire TCCR1A register to 0
TCCR2B = 0; // set entire TCCR1B register to 0

if (i2cReg[I2C_CONF_WATCHDOG_TIMEOUT]) {
// enable Timer2 overflow interrupt:
bitSet(TIMSK2, TOIE2);
// set 1024 prescaler
bitSet(TCCR2B, CS12);
bitSet(TCCR2B, CS10);
}

redLightOn();
_delay_ms(50);
redLightOff();
}

// update I2C register, save to EEPROM if it is configuration
void updateRegister(int index, byte value) {
i2cReg[index] = value;
if (index >= I2C_CONF_ADDRESS) {
EEPROM.update(index, value);
if (i2cReg[index] != value) {
i2cReg[index] = value;
if (index >= I2C_CONF_ADDRESS) {
EEPROM.update(index, value);
}
}
if (index == I2C_CONF_BULK_ALWAYS_ON) {
powerOn();
}
if (index == I2C_CONF_WATCHDOG_TIMEOUT) {
resetWatchdog();
}
}
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,19 @@ The firmware is compiled and uploaded to Zero2Go Omini via Arduino IDE (with ATT
The software is written in BASH.

More information about the firmware and software can be found in the user manual: http://www.uugear.com/doc/Zero2Go_Omini_UserManual.pdf

# Firmware build instructions

You can use the provided Dockerfile and Makefile (made with [Arduino-Makefile](https://github.com/sudar/Arduino-Makefile/)) to quickly set up a build environment with all the required dependencies.:

```
cd Firmware/Zero2Go-Omini
docker build -t zero2go-omini .
```

The firmware can then be built with:

```
cd Firmware/Zero2Go-Omini
docker run -ti -v $(pwd):/src zero2go-omini:latest
```