Go Down

Topic: Arduino-izing the AVR Butterfly (Read 33282 times) previous topic - next topic

Brokentoaster

#30
Dec 06, 2008, 01:44 pm Last Edit: Dec 06, 2008, 01:48 pm by Brokentoaster Reason: 1
DaveK: Your files look great I have updated my files with your changes.

http://brokentoaster.com/arduino012_butterfly.zip

beginner

DaveK and Nick: This is awesome work you do, guys. I updated the files with DaveK's latest changes, figured out how to read the light sensor using plain C code (from the original butterfly app), used the Serial.print() from the Arduino library and I have a small working program in less time that it took me before when I was tinkering with AVRStudio. You guys are great!

DaveK

Here is a short example of reading the light sensor and outputting the result.

It is really nice to be able to do stuff like this so easily. Yay Arduino!

Code: [Select]

void setup() {
 Serial.begin(9600);
}

void loop() {
 // The light sensor is connected to pin 2
 Serial.println( analogRead( 2 ) );
 delay( 250 );
}

beginner

Really?? Awesome! I had no idea it is this easy, I was using the ADC_read() in the original bf_gcc app. I'll try it tomorrow.

Just a question though: how come the light sensor is on analog pin2? I thought on Butterfly it is on PF2 while Arduino analog pin2 is mapped to PC2?! Is there a mapping somewhere in the core files for PortF on Butterfly?

DaveK

Quote
how come the light sensor is on analog pin2? I thought on Butterfly it is on PF2 while Arduino analog pin2 is mapped to PC2?!


Right, on the Mega168 ADC2 is on PC2 and on the Mega169 it is on PF2.

The trick is that the 'pin' parameter specified in analogRead is used to directly set the MUX3..0 bits in ADMUX to select which ADC pin is connected to the ADC. It doesn't go through any mapping routines, so you end up getting the right ADC pin anyway.

Code: [Select]

int analogRead(uint8_t pin)
{
     uint8_t low, high, ch = analogInPinToBit(pin);

     // set the analog reference (high two bits of ADMUX) and select the
     // channel (low 4 bits). ┬áthis also sets ADLAR (left-adjust result)
     // to 0 (the default).
     ADMUX = (analog_reference << 6) | (pin & 0x0f);

DaveK

I should mention that if you change boards.txt:bfly.build.f_cpu you will need to exit and reopen Arduino to get it to reload the info from the file.

DaveK

I've taken a hack at setting up a pin mapping for the Butterfly.

I mapped PORTB, PORTD and four of the JTAG bits in PORTF. If you unprogram the JTAG fuse you can use those four for general IO or as additional ADC inputs.

I didn't map pins you can get at, but that aren't very useful for general purpose IO, like the USI bits or TXD/RXD. You can of course access them via the usual methods, but you can't get to them with digitalWrite (which is ok, because it wouldn't work anyway). Some of these pins are useful for things like pin change interrupts, but I thought they'd be confusing to map them in.

I also set up a pins_butterfly.h file with names of various pins so that you can refer to the SPEAKER pin, PBPIN7 pin, or TEMP a2d input, VOLT a2d input, etc.

I updated pins_arduino.c and included pins_butterfly.h in wiring.h. You can download the files. The archive has the previous changes I've made as well.

beginner

Great stuff! I just download the files, change a bit my small test app and it works like a breeze.

One question: if I don't mess with the JTAG fuses, are there any other pins that could be used for analog IN?

Second one: are there problems using the joystick as input pins? I remember seeing somewhere something about this.

DaveK

Quote
if I don't mess with the JTAG fuses, are there any other pins that could be used for analog IN?


I believe you can use the PORTF4..7 for analog input regardless of the JTAG fuses. You only have to turn off JTAG if you want to use them for digital IO.

I should probably put some names on those pins for analog use, the digital IO names, JTAGPINn, won't work for analogRead, and as long as ADC0..3 are named, ADC4..7 probably ought to be as well.

Quote

are there problems using the joystick as input pins? I remember seeing somewhere something about this.


You can use the joystick pins for general IO, as long as you keep in mind that if you use the joystick you'll short to ground whatever you have attached to the pin.

DaveK

I did some experimenting with setting up a library for the Butterfly. I wrote a Butterfly temperature library, which you can download.

The sample is included in the library, but it looks like this:

Code: [Select]
/*
* TempSense
*
* Read the Butterfly temperature sensor and output
* the result in either Celsius or Fahrenheit. Also
* supports 8x oversampling for improved accuracy.  
*
*/

#include <butterfly_temp.h>

void setup() {
 Serial.begin(9600);
}

void doSamples(){
 Serial.print("Default: ");
 Serial.println( TempSense.getTemp() );  
 
 Serial.print("CELSIUS: ");
 Serial.println( TempSense.getTemp(CELSIUS) );  

 Serial.print("FAHRENHEIT: ");
 Serial.println( TempSense.getTemp(FAHRENHEIT) );  
}

void loop() {  
 Serial.println("** With oversampling off **");
 doSamples();
 
 Serial.println("** With oversampling on **");
 TempSense.overSample = true;
 doSamples();

 Serial.println("** Reset default **");
 TempSense.units = FAHRENHEIT;
 doSamples();

 while(true);
}



The output looks like this:
Code: [Select]

** With oversampling off **
Default: 21
CELSIUS: 21
FAHRENHEIT: 69
** With oversampling on **
Default: 21
CELSIUS: 21
FAHRENHEIT: 69

Brokentoaster

Code: [Select]
butterfly_temp.cpp: In member function 'int TempSensor::getTemp(int)':
butterfly_temp.cpp:19: error: 'TEMP' was not declared in this scope


I guess TEMP is supposed to be defined somewhere as the pin for the temp sensor?

beginner

I didn't try the library but I believe TEMP is defined in the new pins_butterfly.h file added by DaveK which is included in wiring.h

DaveK

Correct, to use the library you'll need the latest version of my butterfly.zip which includes the pin mappings.

I included the pin mappings into the Butterfly core wiring because it seems to me they make the most sense there. If you're running on a Butterfly there are certain things built in, which I think it makes sense to have the core reflect. For example, sensors and port-based pin names (because the pins are physically arranged into port-oriented header blocks). If the pins were in a simple linear arrangement such as on the Arduino, it would make sense to just number them, but I think that with the Butterfly's pin arrangement that would be more confusing.

Also, incidentally, last night I updated the pins_butterfly.h file to include names for ADC4..7, for use with analogRead.

DaveK

Does anyone have any strong opinions for keeping the code that is enclosed in:

#if defined(__AVR_ATmega168__)

and is currently commented out?

I'd like to see it go away, as it seems unlikely to be useful on the Butterfly and it gets in the way.

Brokentoaster

I'm in favour of removing them. As we are running a new core directory they have no substantial relevance whatsoever. My only reasons for keeping it in were

  • To check against what the normal arduino setup was when changeing the code for the butterfly
  • To assist in re merging the butterfly core into the Arduino core code.

I don't think these reasons are really good ones versus the clarity of code after it is removed.
You could also remove the commented out __atmega169__ lines as well as they didn't seem to do any good at all.

Go Up