Inuput Devices

Though I'd broached input devices in the output devices section (with a photoresistor), I wanted to start working towards my final project by incorperating a thermistor into my design. Though Neil had demonstrated some nice visual interfaces for viewing the output from the thermometer, I was planning to use mine as a threshold switch for heating a molten wax bath. As this was the case, all it needed to do was detect that it was above a certain temperature, and turn the heater off, or below a certain temperature and turn the heater on.

As a heater, I was planning on using an incandescent lightbulb run off of AC. This would mean the need to switch 120V, which I knew I could easily do with a relay, but wanted to see if I could do with a MOSFET. I was aware that nothign in the library could handle 120V, but I figured that I could do a mockup for testing purposes.

The first problem to solve was that the MOSFET can only run power in one direction. If I were to successfully switch AC, I would have to come up with a way to run power in one directions, regardless of the AC direction. The solution to this seemed to be a diode array like the one below.

	http://tahmidmc.blogspot.com/2012/11/controlling-ac-load-with-mosfet.html

I started my schematic by modifying Niels board to use an ATTiny44, which gave me a free pin for signalling the MOSFET. I decided it would be easier to design everthing into one board, then once everything was connected, add headers to break everything into separate baords in separate schematics. Below is the first board, and then all of the subsequent breakout boards.

Total Board

Themometer Logic Board

AC Switch and Diode Array

Thermometer Probe

The AC swtich features larger leads in an attempt to reduce resistance for the higher voltages and currents. Additionally, two of the four pins of the breakout headers were soldered together to allow a larger input path for current into the circuit.

The boards, cut and wired, are shown below.

Cut Boards

Stuffed and Wired Boards

The next step was taking Neil's code and modifying it to run with an ATTiny44. Mainly, this meant combing the code for references to the ATTiny45 registry, and making the appropriate corrections. The finished code can be seen below.

	//
//
// hello.temp.45.c
//
// thermistor hello-world
//    9600 baud FTDI interface
//
// Neil Gershenfeld
// 10/27/10
//
// (c) Massachusetts Institute of Technology 2010
// This work may be reproduced, modified, distributed,
// performed, and displayed for any purpose. Copyright is
// retained and must be preserved. The work is provided
// as is; no warranty is provided, and users accept all 
// liability.
//

#include 
#include 

#define output(directions,pin) (directions |= pin) // set port direction for output
#define set(port,pin) (port |= pin) // set port pin
#define clear(port,pin) (port &= (~pin)) // clear port pin
#define pin_test(pins,pin) (pins & pin) // test for port pin
#define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set
#define bit_delay_time 102 // bit delay for 9600 with overhead
#define bit_delay() _delay_us(bit_delay_time) // RS232 bit delay
#define half_bit_delay() _delay_us(bit_delay_time/2) // RS232 half bit delay
#define char_delay() _delay_ms(10) // char delay

#define serial_port PORTA // changed to PORTA from PORTB b/c 14.3.1
#define serial_direction DDRA // changed to DDRA b/c of above.
#define serial_pin_out (1 << PA4) // changed to PA4, which is USCK on ATTiny44

void put_char(volatile unsigned char *port, unsigned char pin, char txchar) {
   //
   // send character in txchar on port pin
   //    assumes line driver (inverts bits)
   //
   // start bit
   //
   clear(*port,pin);
   bit_delay();
   //
   // unrolled loop to write data bits
   //
   if bit_test(txchar,0)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,1)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,2)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,3)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,4)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,5)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,6)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   if bit_test(txchar,7)
      set(*port,pin);
   else
      clear(*port,pin);
   bit_delay();
   //
   // stop bit
   //
   set(*port,pin);
   bit_delay();
   //
   // char delay
   //
   bit_delay();
   }

int main(void) {
   //
   // main
   //
   static char chr;
   //
   // set clock divider to /1
   //
   CLKPR = (1 << CLKPCE);
   CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
   //
   // initialize output pins
   //
   set(serial_port, serial_pin_out);
   output(serial_direction, serial_pin_out);
   //
   // init A/D
   //
   ADMUX = (0 << REFS1) | (0 << REFS0) // VCC ref
      | (0 << ADLAR) // right adjust
   //   | (0 << MUX3) | (1 << MUX2) | (1 << MUX1) | (1 << MUX0); // 20(PB4-PB3)
      | (0 << MUX5) | (0 << MUX4) | (0 << MUX3) |(0 << MUX2) | (0 << MUX1) | (1 << MUX0);
   ADCSRA = (1 << ADEN) // enabled
      | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // prescaler /128 check to see if this is consistent with the tiny44 internal clock******
   ADCSRB = (1 << BIN); // bipolar mode
   //
   // main loop
   //
   while (1) {
      //
      // send framing
      //
      put_char(&serial_port, serial_pin_out, 1);
      char_delay();
      put_char(&serial_port, serial_pin_out, 2);
      char_delay();
      put_char(&serial_port, serial_pin_out, 3);
      char_delay();
      put_char(&serial_port, serial_pin_out, 4);
      char_delay();
      //
      // initiate conversion
      //
      ADCSRA |= (1 << ADSC);
      //
      // wait for completion
      //
      while (ADCSRA & (1 << ADSC))
         ;
      //
      // send result
      //
      chr = ADCL;
      put_char(&serial_port, serial_pin_out, chr);
      char_delay();
      chr = ADCH;
      put_char(&serial_port, serial_pin_out, chr);
      char_delay();
      }
   }


   /* if (ADCSRA < #)
   {
      pin write high
   }
   else
   {
      pin write low
   }
   */

And the make file below

	PROJECT=temp_read
SOURCES=$(PROJECT).c
MMCU=attiny44
F_CPU = 8000000

CFLAGS=-mmcu=$(MMCU) -Wall -Os -DF_CPU=$(F_CPU)

$(PROJECT).hex: $(PROJECT).out
	avr-objcopy -O ihex $(PROJECT).out $(PROJECT).c.hex;\
	avr-size --mcu=$(MMCU) --format=avr $(PROJECT).out
 
$(PROJECT).out: $(SOURCES)
	avr-gcc $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)
 
program-bsd: $(PROJECT).hex
	avrdude -p t44 -c bsd -U flash:w:$(PROJECT).c.hex // changed from 45 to 44

program-dasa: $(PROJECT).hex
	avrdude -p t44 -P /dev/ttyUSB0 -c dasa -U flash:w:$(PROJECT).c.hex // changed from 45 to 44

program-avrisp2: $(PROJECT).hex
	avrdude -p t44 -P usb -c avrisp2 -U flash:w:$(PROJECT).c.hex // changed from 45 to 44

program-usbtiny: $(PROJECT).hex
	avrdude -p t44 -P usb -c usbtiny -U flash:w:$(PROJECT).c.hex

program-dragon: $(PROJECT).hex
	avrdude -p t44 -P usb -c dragon_isp -U flash:w:$(PROJECT).c.hex // changed from 45 to 44

An exciting development during this process was I finally found a patch to connect my computer to the FabISP, which had been bothering me for some time now. Unfortunately this saw the apperance of a new error code:

	usbtiny_transmit:error sending control message: Operation not permitted.