Assignment 9: Electronic Inputs

This week we learned how to use electronic inputs to attach sensors to a microcontroller. I decided to try using the Step Response sensors that utilize two piece of copper generating an electric field and the dielectric effect.

Designing the Board

I decided to modify the microcontroller I'd designed in the earlier assignment. Based on Neil's Transmit-Receive Board and my own board, this is what I came up with:

I milled it using the Modela. The first time I tried milling it, the board actually pulled up off the sacrificial layer. When I tried a second time, I made sure to push down the board harder to make sure the tape really stuck, and it worked fine.

I decided to first program it and make sure it was working before trying anything fancy with the copper pads, so I wanted to attach them reversibly (it didn't occur to me until after I'd left the shop that I could have done this using my own homemade rainbow ribbon) so I use alligator clips and wires around the pins. The whole thing was a bit of a mess because of the number of wires from the different boards, and the fact this week I used a USB hub which added more cables. So what I did was tape everything down to a sheet of paper while programming.

I tried programming it by modifying the existing code and modifying it for use with the ATtiny44 instead of the ATtiny45. Unfortunately, I'm still having a lot of difficulty understand C code and how to interface with the electronics because what showed up in the serial port seemed to be frozen (there was no response to any kind of external input like my finger). I thought there might be some timing or refreshing problems since my circuit uses an external clock, so I tried changing around some of the variables related to the clock to match the 20 MHz frequency, but that didn't seem to work either. At this point, I'm unfortunately at a bit of a loss, but hopefully one of the TA's will have input at a later office hours.

Here is the modified code currently. Most of it is the same, except for the ports it's receiving and transmitting from, and the MUX channel selected. I changed the clock variables back to Neil's original code, since I'm not 100% certain is that's the problem.

//                                                                                                
// hello.txrx.45.c                                                                                
//                                                                                                
// step response transmit-receive hello-world                                                     
//    9600 baud FTDI interface                                                                    
//                                                                                                
// Neil Gershenfeld                                                                               
// 11/6/11                                                                                        
//                                                                                                
// (c) Massachusetts Institute of Technology 2011                                                 
// Permission granted for experimental and personal use;                                          
// license for commercial sale available from MIT.                                                
//                                                                                                

#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 settle_delay() _delay_us(100) // settle delay                                             
#define char_delay() _delay_ms(10) // char delay                                                  
#define nloop 100 // loops to accumulate                                                          

#define serial_port PORTA
#define serial_direction DDRA
#define serial_pin_out (1 << PA1)
#define transmit_port PORTB
#define transmit_direction DDRB
#define transmit_pin (1 << PB2)

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 unsigned char count;
   static uint16_t up,down;
   //                                                                                             
   // 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);
   clear(transmit_port, transmit_pin);
   output(transmit_direction, transmit_pin);
   //                                                                                             
   // init A/D                                                                                    
   //                                                                                             
   ADMUX =  (0 << REFS1) | (0 << REFS0) // Vcc ref                                                
     // | (0 << ADLAR) // right adjust                                                            
    | (0 << MUX5) | (0 << MUX4) | (0 << MUX3) | (1 << MUX2) | (1 << MUX1) | (1 << MUX0); // PA7   
   ADCSRA = (1 << ADEN) // enable ADC                                                             
      | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
   ADCSRB = (0 << ADLAR);
 // prescaler /128 --                                                                           
   // division factor between system clock and input clock                                        
   //                                                                                             
   // main loop                                                                                   
   //                                                                                             
   while (1) {
      //                                                                                          
      // accumulate                                                                               
      //                                                                                          
      up = 0;
      down = 0;
      for (count = 0; count < nloop; ++count) {
         //                                                                                       
         // settle, charge                                                                        
         //                                                                                       
         settle_delay();
         set(transmit_port, transmit_pin);
         //                                                                                       
         // initiate conversion                                                                   
         //                                                                                       
         ADCSRA |= (1 << ADSC);
         //                                                                                       
         // wait for completion                                                                   
         //                                                                                       
         while (ADCSRA & (1 << ADSC))
            ;
         //                                                                                       
         // save result                                                                           
         //                                                                                       
         up += ADC;
         //                                                                                       
         // settle, discharge                                                                     
         //                                                                                       
         settle_delay();
         clear(transmit_port, transmit_pin);
         //                                                                                       
         // initiate conversion                                                                   
         //                                                                                       
         ADCSRA |= (1 << ADSC);
         //                                                                                       
         // wait for completion                                                                   
         //                                                                                       
         while (ADCSRA & (1 << ADSC))
            ;
         //                                                                                       
         // save result                                                                           
         //                                                                                       
         down += ADC;
         }
      //                                                                                          
      // 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);
      //                                                                                          
      // send result                                                                              
      //                                                                                          
      put_char(&serial_port, serial_pin_out, (up & 255));
      char_delay();
      put_char(&serial_port, serial_pin_out, ((up >> 8) & 255));
      char_delay();
      put_char(&serial_port, serial_pin_out, (down & 255));
      char_delay();
      put_char(&serial_port, serial_pin_out, ((down >> 8) & 255));
      char_delay();
      }
   }