project proposal
press fit construction kit
pcb fabrication
3D scanning and printing
electronics design
molding and casting
embedded programming
cnc machining
[07] ~ EMBEDDED PROGRAMMING |
This week we were tasked with programming our board to do something. Since I had already gotten my board programming for electronics design week I set a goal of controlling the RGB LED with the internal temperature sensor on the ATTiny. I also wanted to get serial communication working so I could easily debug future boards and programs. I first started programming in C, using GCC and avrdude to compile and program the board. I got the hello.ftdi.44.ftdi test code working (linked on this page) with the term.py script without too much trouble. The workflow looks something like this: (and is linked here)
I read through the section of the ATTiny44 datasheet that explains how to use the internal temperature sensor on the ADC and slapped together code that I thought would work. I then tried to modify the hello.ftdi code to output the temperature rather than echo'ing characters but I got no output. Only when my temperature values fell within some range (e.g., 30-125 or thereabouts) was I able to see characters in the terminal. My suspicion is that data was getting through but term.py wasn't showing it because it didn't fall within the character set. I looked at the source for term.py but didn't see any obvious way of typecasting the incoming char to an int (though I'm sure it's easily do-able with the requisite python skills). I even tried just outputting an integer that incremented every loop but got weird behavior like this (below) where it counts fine initially but then decides to skip around. So... I decided to jump ship and program in the Arduino environment. I had already configured my Arduino environment to program ATTiny chips (using the extremely awesome high-low tech tutorial so transitioning was pretty seamless. The thing I really like about using the Arduino environment is that you have access to really helpful high-level funcitons and libraries like SoftwareSerial but are still able to manipulate bits and registers directly. I literally just had to copy and paste my C-code into the arduino environment and it compiled successfully. That's not to say it worked immediately... I spent a while debugging the output the internal temperature sensor was giving me. Ultimately the problem turned out to be that I had set the ADCSRA register to 0b10000000 (with the command Here's the code I used to read the temperature: Stepping through it line by line... The first line sets the ADMUX register to use the 1.1V reference in the ADC and selects ADC channel 8 (this tells the chip to give a temperature reading). We then wait a few ms for the register to settle. The ADC conversion is started by setting the ADSC bit of the ADCRSA register. Then, we use a while loop to wait until that ADSC bit goes low (this bit will be toggled automatically by hardware when the ADC is done converting). We then combine the low byte and high byte to get our 10 bit temperature value. The temperature/LSB relationship is essential 1 degreees C/LSB so to convert from ADC reading to degrees C you just have to subtract a constant offset. To test the temperature measurement I subjected the chip to the heat gun and output the sensed temperature to the serial monitor. I generated this graph from the data. It looks about right. We definitely see the exponential decay and the sped-up exponential decay when I blow room-temp air over the top of it when it reaches about 50 degrees C. Now, to couple the ADC reading to the RGB LED... I mapped the temperature values to a 0-255 range and used the analogWrite function (which is really PWM) to adjust the brightness of the colors. Unfortunately only my red LED seemed to want to dim. The green and blue seemed to prefer to be either on or off and they toggled at pwm = 128 (out of 255). I assumed it was a hardware issue given that red LED's have the lowest turn-on voltage but now I'm wondering whether it's an internal timer issue. I'd have to investigate how Arduino is implementing the analogWrite() function... Anyway... Here's the final result: Source Files: Arduino Sketch
|