I spent the whole afternoon trying to make the arduino works with 2 dataflash chips. A coupe of really stupid code mistakes and some weird stuffs later, it worked. You can now have 2 instances of ATD45DB161D class. For example one will use the pins 2, 4 and 5 for SS, RESET and WP and the other one will use pins 10,8 and 7.
I couldn’t make SS work with an other pin than the pin 10 until I ran across forum post. So I have to set both the requested SS pin and pin 10 (hardwired SS pin) high before setting the SPCR register so that the atmega168 becomes master.
So I moved the SPCR initialization to a new method astutely called Enable. And I added its counterpart called Disable which drives the SS pin high.
So before using a given Dataflash chip, you’ll have to call Enable before using it. And call Disable when you are done with it.
As I’m not happy with the current design, I created a new branch for this dev.
You can find it [here].
Any ideas/suggestions for a cleaner/safer way to handle multiple SPI device are welcome 🙂
: Arg, I should have checked Atmel site. They have an application note called AVR151: Setup And Use of The SPI.
 (it’s the last one. I swear 🙂 ) I moved the SPI master init into a new function (spi_init). It’s a little bit cleaner now. But it’ll stay in a branch until I run more tests and have some feedback.
Some months ago, I bought a 4DSystem’s µDRIVE-uSD-G1 (microDRIVE) from Sparkfun. It’s basically a serial module which let you access a microSD memory card (from 512Mb to 2Gig). You may wonder why use an external module as SD cards have a SPI interface? The main reason is … laziness. All file-system operations are performed by the module. So why bother coding fat16 support or whatever? Unfortunately, the current microDRIVE firmware only supports raw access.
Anyway, I wrote a small module for the current firmware. It was implemented as a template in order to support various serial implementations. The serial class must provide the following methods :
- uint8_t read()
- void print(uint8_t)
- int available()
It’d have been better if all the serial implementations derived from a same interface. But as I didn’t want to modify the base Arduino code (and as i said earlier, because I’m lazy), I went for the easy/brutal way. And you’d probably never have more than one microDRIVE. At least you want raid 😀
I tested Arduino‘s HardwareSerial and SoftwareSerial, as long as ladyada’s AFSoftSerial. None of the software implementations work 😐 Only soft read is working (hardware tx was used). As software serial is working for the serial LCD, I think the problem might be the autobaud detection during microDRIVE initialization… Or not…
Be careful! There’s a bug in the rev1 firmware. The internal memory address is not incremented to the next sector block after a write operation. It was corrected in the rev2.
I just got my hands on a 20×4 serial LCD from Sparkfun. It’s basically a standard LCD with a little PIC based serial TTL interface board plugged on it.
10 lines of code and 3 wires later, I had a wonderful “Hello world” displayed on screen. The only problem is that I was using pin 1 (TX) which is shared with the serial USB interface. So when the sketch is uploaded, it’s also sent to the SerLCD. And you end up with garbage on screen. Hopefully, Arduino comes with a soft serial class. It lets you use custom pins for serial communication. The only downside it that it can only run at 4800 baud or 9600 baud.
Next serial fun : 4DSystem’s µDRIVE-uSD-G1.
Here’s the result!
The mandatory piece of code.
#define SERLCD_CMD 0xFE
#define SERLCD_CLEAR 0x01
#define SERLCD_MOVE1_R 0x14
#define SERLCD_MOVE1_L 0x10
#define SERLCD_SCROLL_R 0x1C
#define SERLCD_SCROLL_L 0x18
#define SERLCD_DISP_ON 0x0C
#define SERLCD_DISP_OFF 0x08
#define SERLCD_UNDERLINE_CURSOR_ON 0x0E
#define SERLCD_UNDERLINE_CURSOR_OFF 0x0C
#define SERLCD_BLINKING_CURSOR_ON 0x0D
#define SERLCD_BLINKING_CURSOR_OFF 0x0C
#define SERLCD_SET_CURSOR_POS 0x80
#define SERLCD_CURSOR_OFF 0x0C
#define rxPin 6
#define txPin 7
char *str = "BlockoS! :)";
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
for(cursor=str; *cursor!='\0'; ++cursor)
/* Nothing */
Last month I ordered some DataFlash (AT45DB161D) chips from Sparkfun. The AT45DB161D is a flash memory with SPI interface. It’s able to store up to 16Mbits of data.
With the DataFlash library for the Arduino in one hand and a solder iron in the other, I was ready to test the beast. Unfortunately the chip is an 8 pin SOIC. So I had to solder it on a SOIC-to-DIP pcb. Luckily Sparkfun (again) was selling an 8-Pin SOIC to DIP Adapter. With my legendary bad luck, I realized afterward that the SOIC connectors were too small. I had to bend them a little 😐 The soldering was a massacre…
Anyway, after what seemed to be an hour (in fact it was only 5 minutes) I was finally over with the whole mess. I plugged the DataFlash to the breadboard and connected it to the Arduino (important note : it was an old NG revision). I had to make a simple circuit to convert the 5V output from the Arduino to 3.3V. After a bunch of attempts which ended in burning a 3.3V voltage regulator, I run the test program.
And … Nothing happened. I was getting a bunch of 0000 and FFFF. And the result was the same even if the chip wasn’t connected to the Arduino.
To make things short after destroying another DataFlash (I broke the pins) and hazardous code experiments, it appeared that the old revision of the Arduino NG had problems with SPI.
This was a good excuse to buy the new Diecimila Arduino board 🙂 The 9V output was changed for a 3.3V one. I didn’t need my dummy circuit anymore. I also bought a bunch of 8pin SOIC to DIP pcbs from ebay (larger than the Sparkfun ones). The soldering work was easier this time and everything was setup for testing in less than 10 minutes. I uploaded the test program to the board…
Miracle, it worked!
The Arduino DataFlash library was written for the B revision. A lot of things changed from the B to the D revision of the DataFlash. This was a call to write a new library. Unfortunately the on I wrote is specific to the AT45DB161D. It only supports standard page size (528 bytes) and all the security commands are unimplemented. I first need to get extra chips before working on it as these commands can brick the DataFlash.
You can grab the AT45DB161D library for the Arduino here :
You’ll have to put those files in $ARDUINO/lib/targets/libraries/at45db161d ($ARDUINO being the name of you arduino directory).
[Documentation] (Doxygen rules)
Now, I have to find out how to interface the Arduino board to the pcengine. I think I’m up again for a month of painful experiments 🙂
As I managed to make the Arduino software work under linux, I did this week Make weekend project : “Intro to the Arduino”.
It’s really simple. When you push a button connected to pin 2, a led connected on pin 9 will fade in and out.
Easy isn’t it? Unfortunately I’m pretty bad in electronic. My first try made the led blink nervously. After several unsuccessful attempts, I decided to make things work step by step.
- The breadboard
How does this thing work? After looking at this tutorial, it appears that my breadboard is separated by the center gap in 2 independent parts. Each part has 16 rows and 5 columns of contacts. All the contacts of a row are connected together.
- The led
I put the led on the breadboard and connected it on pin 9. I tested it with the blinking led example. As always it didn’t work on the firsts attempt. The led was connected the wrong way.
- The button
I spent a lot of time on it. I first have to figure out how it was working. So I modified the previous setup and put the button between the pin and the led. Once I got it working, I connected it to pin 2. Then according to the original schematic, I had to connect the rest of the circuit to the power pins.
Ten minutes later it was finally working! Here’s a totally wonderful and awesome video (edited with Avidemux) to prove it 🙂
[flashvideo filename=wp-content/uploads/2008/04/arduino01.flv /]
The road will be long and hard before I get the backup thingie for pc-engine done…
Months ago, I bought an Arduino. It comes with a nice ide but I always used it under Windows. This summer I decided to stop using Windows and I haven’t played with the Arduino since then.
Some days ago I purchased some stuffs from Sparkfun (some dataflash, resistors, etc…) in order to make some kind of backup device for the pc-engine. So I decided to install the Arduino softwares on my box. I’m currently running a Fedora core 7 for amd64. There are instructions for Fedora core 6 on Arduino site. But as I’m running on an amd64 I had to recompile some stuffs.
There’s no official package for sun’s java on Fedora. Just follow the instructions from Jan K. Labanowski of the Computational Chemistry List, Ltd and you are done in less than 10 minutes.
- AVR tools
It’s the easiest part. Fedora core 7 includes all you need. You’ll have to install the following packages:
Arduino comes with a precompiled version of RXTX. Unfortunately it’s a 32bits version. You’ll have to recompile it or you’ll have some nasty messages when trying to run Arduino. Well, it won’t crash immediately. You’ll be able to set the program directory. But once you press OK, it will crash and you’ll get a nice error message.
After trying to compile the CVS version of RXTX, I went for a release vesion. The latest one is 2.1-7r2. According to the INSTALL file, all I had to do was the standard “./configure; make; make install” combo.
Unfortunatelly, the kernel headers test from the configure script failed. It’s trying to compile some piece of C code but. Here’s the error :
error: 'UTS_RELEASE' undeclared (first use in this function) It seems that all distros are patching RXTX to remove the use of this variable. In fact it’s only used for a sanity check. If the current kernel version is different from the one RXTX was compiled for it will prompt some error message. If you really want to use it you’ll have to add the right header in the configure script (check_kernel_headers) and some various C files.
I went the dirty way and simply removed it. Hopefully there’s a patch from the nslu2-linux project which will do the work for you on the sources. But you’ll still have to remove the check_kernel_headers() from the configure script.
But that’s not the end of your problems! make install won’t work. You’ll have the following error :
make: Entering directory `//rxtx-2.1-7r2'
make: Nothing to be done for `all-am'.
make: Leaving directory `//rxtx-2.1-7r2'
libtool: install: `x86_64-unknown-linux-gnu/librxtxRS485.la' is not a directory
Try `libtool --help --mode=install' for more information.
make: *** [install] Error 1
Hopefully this issue is addressed in the RXTX faq.
After installing RXTX, edit /usr/java/jdk1.6.0_02/jre/lib/javax.comm.properties (create the file if it’s missing) and add the following line :
We are now ready to run the Arduino software!
The latest version is Arduino 0009. Install it wherever you want. Let’s say ~/arduino. When you are done go to ~/arduino/lib. Remove RXTXcomm.jar and librxtxSerial.so. Then edit ~/arduino/arduino and modify both CLASSPATH and LD_LIBRARY_PATH to point to the directory containing RXTXcomm.jar and librxtxSerial.so. Here’s what it looks like on my system :
At this point we are nearly done. Don’t forget to give your user the permission to the usb device (/dev/ttyUSB0 in my case). Plug the Arduino board and launch the ide. There’ll be some gcc warnings. Don’t pay attention to them.
First set the serial port. Go to Tool > Serial Port and choose the correct interface. If you don’t know it, leave the menu and unplug the board. Go to the Serial Port menu and note the currently listed interface. Replug the board. And return to the Serial Port menu. A new usb interface may have appeared. It’s the interface the board is connected to.
You’ll have to check if the ide is set to the microcontroller. If it’s not the case when you’ll want to upload your code to board, you’ll have the following error:
avrdude: Expected signature for ATMEGA168 is 1E 94 06
Take your board and look for the chip type. You can’t miss it, it’s written on it 🙂 To change the microcontroller go to Tools > Microcontroller (MCU) and choose your chip (ther’s an ATMEGA8 on my board).
At this point everything should be alright.