Pages: [1]   Go Down
Author Topic: Using an AtTiny as a configurable environment controller  (Read 539 times)
0 Members and 1 Guest are viewing this topic.
Hurley, NY
Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a complex Arduino-based solar hot water controller that I can configure and monitor using a 100 ft. serial cable. (I'm not using a modern Arduino, but instead one that connects via a Max232 -- USB does not have an adequate range.)  This normally works okay and I can use its bootloader(s) (there's a master and a slave) to upload new firmware.  Occasionally, though, there are problems.  When the serial cable gets unplugged from the computer, that 100 feet of unterminated wire pulls in all sorts of random noise and repeatedly resets the controller via the DTR line (which is connected to the reset line via a capacitor -- as is the case in Arduino Diecimilas). To make the solar controller more reliable, I needed a way to switch off the capacitive connection between DTR and reset and only enable it when I need to upload new firmware.  So I build a circuit based on an AtTiny85 (which is programmable from within the Arduino environment -- see https://www.sparkfun.com/products/11460 ) that monitors the serial transmit line (transmit from the computer, receive to the Atmega328s) looking for a string of the form '!X[digit]' -- if it sees that, it turns on a pin that, using a 4016 CMOS switch, connects the DTR to the Atmega reset pin for a length of time equal to 10 raised to the power of [digit] seconds.  During that time, I can reflash the Atmega328s as usual.  Otherwise I can only read data from the Atmega328s and send them serial-based queries and instructions.  This has made the solar controller much more reliable.  Here's the source code of the AtTiny:

Code:
/*
SERIAL WATCHDOG
June 27, 2013
Judas Gutenberg
Serial watchdog for the AT Tiny 45/85/84
It monitors a serial line for !X[digit] or !R
if the former, it makes pin 0 go high for 10^[digit] seconds
if the latter, it sends a low-going pulse out of pin 1 for 1/100th of a second
i use this as a serial watchdog on an Arduino, allowing
me to keep the capacitor on the reset pin disconnected most of the time
so a disconnected serial cable won't throw the arduino in a loop
i use the !R to force a hardware reset of both a master and slave arduino.
*/

#include <SoftwareSerial.h>
SoftwareSerial softSerial(3, 4); // RX, TX
char byteThird;
char byteSecond;
char byteFirst;
long milliStart;
long timeOn=10000;
int len=0;

void setup()
{
pinMode(0, INPUT);
digitalWrite(0,LOW);
softSerial.begin(19200);
 
}


void loop()
{

if (softSerial.available() > 0)
{
byteFirst=byteSecond;
byteSecond=byteThird;
byteThird = softSerial.read();
}
if(byteFirst=='!')
{
if(byteSecond=='X')
{
//softSerial.println(byteThird);
len=(int)byteThird-48;
milliStart=millis();
pinMode(0, OUTPUT);
digitalWrite(0,HIGH);
  clearBytes();
}
if(byteSecond=='R')
{

pinMode(1, OUTPUT);
digitalWrite(1,HIGH);
delay(10);
digitalWrite(1,LOW);
  delay(10);
digitalWrite(1,HIGH);
pinMode(1, INPUT);
clearBytes();
}
}

if(milliStart+( powerof(10,len) *1000)<millis())
{
digitalWrite(0,LOW);
pinMode(0, INPUT);
 
}
delay(500);
}

void clearBytes()
{
byteThird=0;
byteSecond=0;
byteFirst=0;
}


unsigned long powerof(long intin, byte powerin)
//raises intin to the power of powerin
//not using "pow" saves me a lot of Flash memory
{
  unsigned long outdata=1;
  byte k;
  for (k = 1; k <powerin+1; k++)
  {
    outdata=outdata*intin;
  }
  return outdata;
}


And here's the schematic for how I attached it to the Atmegas:



learn more about my solar controller here:
http://asecular.com/projects/homebrewsolar.php
« Last Edit: June 29, 2013, 08:54:39 pm by bigfun » Logged

Pages: [1]   Go Up
Jump to: