I am attempting to write a External Watchdog sketch that will check whether a pulse is received within a given time interval (say 15 seconds).
For this I was attempting the following:
int valKICK = 0; // variable to store the read KICK PIN value
void setup() {
pinMode(0, INPUT); // KICK PIN
pinMode(1, OUTPUT); // RESET OUT PIN
}
void loop() {
unsigned long KICK_scan_time_now = millis();// Start Millis Time
unsigned long interval = 15000;
while ((millis() < (KICK_scan_time_now + interval)))
{
valKICK = digitalRead(0); // read the KICK PIN
if (valKICK == 1) {
digitalWrite(1, HIGH); // We received a KICK pulse on D0 - ALL IS OK and program is running
KICK_scan_time_now = millis(); // Reset millis timer
}
}
// Now we have reached the END of our 15 seconds Timeout
// We never received a KICK pulse on D1 during the 15 seconds timeout - ALL IS NOT OK and program is NOT running
if (valKICK == 0) {
digitalWrite(1, LOW); // We now Pull D1 LOW to force a RESET on the remote uP
delay(10);
digitalWrite(1, HIGH); // Pull D1 HIGH to exit RESET
}
However, it seems that millis() is not supported as I am not using any Arduino core.
Is it possible to setup timers within the ATtiny10 to accomplish this?
I have spent hours searching, but cannot find a solution.
I don't understand the logic of the while()
it seems that you do not scan the input unless you are already under 15 seconds.
but.. you constantly set to millis()
so it never can be other than millis()+scan time
===================================
void loop() {
unsigned long KICK_scan_time_now = millis();// Start Millis Time
the normal state is valkick = 0
when it gets an input, it goes to 1
sets the KICK_scan_time_now to equal millis()
why not
loop()
valKICK = digitalRead(0); // read the KICK PIN
if valkick = 1 then kicktim = mills()
if millis() > kicktim+interval then do the digital write bit
are you resetting the micro every time you want to use this ?
if you sent the pulse after 15 second, you could then wait for a new kick to start again.
that could be a variable, 15.0001 seconds, or wait 30 seconds.
it seems that this is more like a snippet and not a full sketch.
assuming a kick bag for some form of martial arts...
the player gets ready.
kicks the bag, starts the timer...
as long as they keep kicking under 15 seconds, the remote does not trigger.
or,
remote goes on, turns on power, player hears the buzzer or sees the start light
then kicks... 15 seconds later the remote gets the signal
Ok, to recap:
When the ATtiny10 boots, it must start a timer that increments from zero to 15 seconds.
During the 15 seconds, we read D0 (Kick Pin) to see if we have received a pulse (250ms) from the remote uP.
If we receive a pulse on D0, we reset the timer to zero and resume increment the timer from zero to 15 seconds.
Should we receive regular pulses on D0 at intervals of less that 15 seconds, we will never get to a 15 seccond timeout.
If the timer reaches 15 seconds timeout and NO pulse has been received on D0, then D1 is briefly pulled LOW for 10ms. This is to reboot the remote uP.
This code could should do better. No while loop, that's what the loop() function is for:
byte valKICK; // variable to store the read KICK PIN value
bool didReset;
unsigned long KICK_scan_time_now;
const unsigned long interval = 15000;
void setup() {
pinMode(0, INPUT); // KICK PIN
pinMode(1, OUTPUT); // RESET OUT PIN
}
void loop() {
if (digitalRead(0)) { // We got kicked.
KICK_scan_time_now = millis(); // Record when it happened.
didReset = false; // Note: no reset done since this kick.
}
else {
if (millis() - KICK_scan_time_now > interval && // timeout
didReset == false) { // and didn't reset yet
digitalWrite(1, LOW); // We now Pull D1 LOW to force a RESET on the remote uP
delay(10);
digitalWrite(1, HIGH); // Pull D1 HIGH to exit RESET
didReset = true; // Mark we handled this timeout.
}
}
}
That is, assuming millis() works correctly on the ATtiny10 - the only core that I found was a mere set of menu entries... without support for functions such as millis(), pinMode() or digitalRead().
@wvmarle
Many thanks.
However, it seems like millis() is not supported on the ATtiny10.
Your code runs great on an UNO, but not on the ATtiny10.
pinMode(), digitalWrite() and delay() do works - the Basic Blink example works fine.
Maybe I should look at structuring the sketch around the delay() function?
Use the timer - the ATtiny10 has a 16-bit timer. Using delay() calls will make you miss punches.
Set it to some sensible prescaler and you can build your own millis()-like function for it: set a timer interrupt to increase an unsigned long variable, use the value of that for your time calculations. Of course you will have to compensate for it not being 1000 ticks per second but some different value.
Check the ATtiny10 datasheet on the appropriate register calls and settings.
wvmarle:
Use the timer - the ATtiny10 has a 16-bit timer. Using delay() calls will make you miss punches.
Set it to some sensible prescaler and you can build your own millis()-like function for it: set a timer interrupt to increase an unsigned long variable, use the value of that for your time calculations. Of course you will have to compensate for it not being 1000 ticks per second but some different value.
Check the ATtiny10 datasheet on the appropriate register calls and settings.
Thanks, but this is way above my programming skills.
I can increase the duration of the incoming pulses - say 100ms.
I could then check for pulses every 10ms.
That way, I "should" get every pulse.
If I set a counter to increment every 10ms.
If a pulse is seen, I reset the counter.
I the counter reaches 1500 (15 seconds) , it means no pulse was received.
It's really not hard to program. Getting the actual settings correct is the hardest. It's what you got to do when you go play with MCU's as limited like this
Lots of examples out there for the atmega328p, which I expect works much the same.
Using anything arduino-like on parts with 1k of flash, or even 2k, is pretty unpleasant. What about a tiny45, or a tiny412 - both are 8-pin chips. the t45 (also available with 2k or 8k flash, as 25 and 85) is a classic AVR, programmed by ISP, and supported by ATTinyCore. Can run at 16MHz w/no crystal, a rare feat in the classic avr world, no hardware serial (though my core provides a builtin software serial that doesn't use PCINTs like SoftwareSerial does, since those are very useful, and SoftwareSerial uses up all of them). They have a USI instead of SPI and I2C, though my core provides a "smart" Wire and SPI library that makes them look like the what the normal library presents. Very widely used (though usually people go for the 85, for the extra flash and ram).
The tiny412 is a new megaavr, programmed via UPDI, and supported by megaTinyCore (see the core documentation for how to easily use a nano or other '328p-based board as a UPDI programmer with just 3 wires and a cap). The 412 and it's larger megaavr brethren are also cheap (cheaper than otherwise similar classic AVRs - i think microchip/atmel is trying to encourage people to use the new product lines), they have some really spiffy new peripherals, and can run at up to 20MHz (actually a bunch of specific speeds, though my core only exposes 20/16/10/8/5/4/1), they all have a real serial port, real I2C, real SPI, since I got my megaTinyCore working right, I have been using the megaavr attiny's in almost every project I do - (they go up to 21 usable I/O pins (17 if you don't want to solder QFN package), with 32k of flash and 2k of ram! The ones where the next-to-last digit is a 1 (the "1-series" even have a DAC for true analog output - the "0-series" is a slightly cheaper product line with a few of the more exotic peripherals removed).
In either event, there's plenty of basic info on the parts in the docs for my core (see SpenceKonde (Spence Konde (aka Dr. Azzy)) · GitHub ), and of course the datasheet contains excruciating detail about everything, but is not exactly casual reading.
loop_count++ ;
if ( loop_count >= ???? ) // need to time loop cycles to put in count for 15 seconds
the sketch is simple enough to do that.
digialWrite (1, LOW)
if (loop_count >+ (????+100) // add for the 10 mS needed
digitalWrite(1, HIGH)