I posted this video guide on Youtube a couple of days ago, though I wanted to announce it in here too.
In this video tutorial I guide you thru how to make a counter application for the Basys2 board, which is an FPGA board from Digilent to those who are unfamiliar with it.
I will show you the required steps of setting up a project in Xilinx ISE, writing the VHDL code for the counter application, writing the pin constraints file (.UCF) and finally generating the bit-file for the Basys2 board.
This video tutorial was actually requested by a reader of the blog, so with this being my first video tutorial, I would like to show you that comments and requests ARE HEARD! 🙂
EDIT:
The Xilinx ISE project files for the tutorial can be downloaded here: Basys2_CounterApp.zip
Evaluation Type: Evaluation Boards Application you used the part in: Evaluation of PIC32 USB Starter Kit II Was everything in the box required?: Yes What were the biggest problems encountered?: It requires some time to find the sufficient examples, and unfortunately most of the examples are pre-compiled HEX-files, so it is impossible to change something in the demos.
Though it is possible to find the same demos in the Microchip Application Library, it’s difficult to get theese working together with the Multimedia Expansion Board.
Scoring Product Performed to Expectations: 10 Specifications were sufficient to design with: 8 Demo Software was of good quality: 8 Demo was easy to use: 7 Support materials were available: 8 The price to performance ratio was good: 9 TotalScore: 50
Prelude
In this review I will be demonstrating and reviewing the PIC32 Multimedia Expansion board. This is a expansion product from Microchip, which extends the capabilities of their PIC32 Starter Kits. In the end you will find my conclusion, whether you should buy this board or not.
In the following review, the Multimedia Expansion board will be called MEB board. Read more…
Once again me and one of my class mates have finished a project in school using the Arduino.
This time it’s an RFID Door Lock made with a real door and a real lock. The lock is turned using a standard 6V servo.
The project was about luxury, and we thought it might be luxurious if the door could be unlock automatically, fx when you come home from shopping, carrying a bag in each hand. This was the beginning of this project.
In the video below you can see a short demonstration of the system.
We thought you might be interested in the code, and to see how we implemented the “Master-system”, so the code can be found beneath. Remember that you should download the Servo library, and the Parallax RFID reader should be connected to the Serial RX pin (Pin 0).
//Start #include <eeprom.h> #include <servo.h>
//Initialiser
Servo servoLock;// create servo object to control a servo // a maximum of eight servo objects can be created
#define RFID_Enabled_Pin 2 // sets RFID enable pin to pin 2 #define servoPin 3 // sets the servo's pin to pin 3 #define LockedPos 10 #define UnlockedPos 110
byte buffer[100];//used to store the incoming bytes from the RFID
byte RFID_Master[10]={'1', '7', '0', '0', '7', 'D', 'B', '2', '4', 'F'};//the secound RFID fob (key) to look for
byte RFID_Slave1[10], RFID_Slave2[10], RFID_Slave3[10];//the first RFID fob (key) to look for
byte i;//used to keep track of which bit to write to
byte i2;//used to erase the RFID fob (key) number from the buffer
boolean DoorLocked;//true if door is locked
byte checkPosition;//used to check if the incomming number is true or false
boolean RFID_Master_Correct;//true if it's the right RFID fob (key), false if not
boolean RFID_Slave1_Correct, RFID_Slave2_Correct, RFID_Slave3_Correct;//true if it's the right RFID fob (key), false if not
boolean RFID_SaveNextRead;
void setup(){
pinMode(13, OUTPUT);//enables the diode on the arduino
pinMode(RFID_Enabled_Pin, OUTPUT);//sets the RFID pin to output
RFID_Enable(false);//used to set the status of the RFID reader
EEPROM_Read_Slaves(); //Lock
PreLock();//locks the arduino on startup
RFID_Enable(true);//used to set the status of the RFID reader
Serial.begin(2400);//sets baudrate
i =1;//sets the varible to 1, and thereby skip the start byte (0x0A) } //Go To //Loop void loop(){//the main loop // Serial data if(Serial.available()){//check if the RFID reader sends anything if(buffer[0]!=0x0A){//check if it the start bit is 0x0A
buffer[0]= Serial.read();//write bit to buffer }else{ //Recieve
buffer[i]= Serial.read();//write next bit to buffer if(buffer[i]==0x0D){//if end bit is send, disable the RFID reader temporary
Serial.print("RFID Tag scanned: ");
RFID_Enable(false);
RFID_Master_Correct =true;
RFID_Slave1_Correct =true;
RFID_Slave2_Correct =true;
RFID_Slave3_Correct =true; //RFID ID // We have read all bytes - we are now going to check them for(checkPosition =0; checkPosition <10; checkPosition++){//Read bit fra 0-9
Serial.print(buffer[checkPosition+1], BYTE); if(buffer[checkPosition+1]== RFID_Slave1[checkPosition]&& RFID_Slave1_Correct ==true){// compares the written bits to "RFID1"
RFID_Slave1_Correct =true;//Slave1 RFID tag is detected }else{
RFID_Slave1_Correct =false;//Slave1 RFID tag is not detected } if(buffer[checkPosition+1]== RFID_Slave2[checkPosition]&& RFID_Slave2_Correct ==true){// compares the written bits to "RFID1"
RFID_Slave2_Correct =true;//Slave2 RFID tag is detected }else{
RFID_Slave2_Correct =false;//Slave2 RFID tag is not detected } if(buffer[checkPosition+1]== RFID_Slave3[checkPosition]&& RFID_Slave3_Correct ==true){// compares the written bits to "RFID1"
RFID_Slave3_Correct =true;//Slave3 RFID tag is detected }else{
RFID_Slave3_Correct =false;//Slave3 RFID tag is detected } if(buffer[checkPosition+1]== RFID_Master[checkPosition]&& RFID_Master_Correct ==true){// compares the written bits to "RFID1"
RFID_Master_Correct =true;//Master RFID tag is detected }else{
RFID_Master_Correct =false;//Master RFID tag is detected } }
Serial.println(""); if(RFID_SaveNextRead ==false&&(RFID_Slave1_Correct ==true|| RFID_Slave2_Correct ==true|| RFID_Slave3_Correct ==true)&& RFID_Master_Correct ==false){//see if the right RFID fob (key) is detected if(RFID_Slave1_Correct ==true){ Serial.println("Slave1 Card Scanned");} if(RFID_Slave2_Correct ==true){ Serial.println("Slave2 Card Scanned");} if(RFID_Slave3_Correct ==true){ Serial.println("Slave3 Card Scanned");} //Door if(DoorLocked ==true){//see if door is locked or not //Unlock
Serial.print("Unlocking...");//if the door is locked then unlocked it
Unlock(5);//unlock with 5ms delay
Serial.println(" Unlocked!"); }else{ //Lock
Serial.print("Locking...");//if the door is unlocked then lock it
Lock(5);//lock with 5ms delay
Serial.println(" Locked!"); } //Vent
delay(1000);// Wait for you to remove the RFID fob (key) }elseif(RFID_Master_Correct ==true&& RFID_SaveNextRead ==false){// If the Master Card is scanned when not in programming mode
Serial.println("Master Card Scanned - Programming mode Enabled");
delay(1000);
RFID_SaveNextRead =true;// Enable programming mode }elseif(RFID_Master_Correct ==false&& RFID_SaveNextRead ==true){// If another card is scanned when in programming mode // Save the Card if(RFID_Slave1[0]==0){// Is the Slave1 Card slot empty? for(checkPosition =0; checkPosition <10; checkPosition++){//Read bit fra 0-9
RFID_Slave1[checkPosition]= buffer[checkPosition+1];// Save the scanned card as Slave1 }
Serial.println("RFID Card saved in: Slave1");
delay(1000); }elseif(RFID_Slave2[0]==0){// Is the Slave2 Card slot empty? for(checkPosition =0; checkPosition <10; checkPosition++){//Read bit fra 0-9
RFID_Slave2[checkPosition]= buffer[checkPosition+1];// Save the scanned card as Slave2 }
Serial.println("RFID Card saved in: Slave2");
delay(1000); }elseif(RFID_Slave3[0]==0){// Is the Slave3 Card slot empty? for(checkPosition =0; checkPosition <10; checkPosition++){//Read bit fra 0-9
RFID_Slave3[checkPosition]= buffer[checkPosition+1];// Save the scanned card as Slave3 }
Serial.println("RFID Card saved in: Slave3");
delay(1000); }else{
Serial.println("No free Card slots");
RFID_Enable(true);//turns on the RFID reader
delay(1000);
RFID_Enable(false);//turns off the RFID reader
delay(1000); }
EEPROM_Save_Slaves();
RFID_SaveNextRead =false; }elseif(RFID_Master_Correct ==true&& RFID_SaveNextRead ==true){// If the Master Card is scanned when in programming mode
Serial.println("Master Card Scanned again - Removing all saved Cards");
delay(1000); // Remove all Slave Cards for(checkPosition =0; checkPosition <10; checkPosition++){//Read bit fra 0-9
RFID_Slave1[checkPosition]=0; } for(checkPosition =0; checkPosition <10; checkPosition++){//Read bit fra 0-9
RFID_Slave2[checkPosition]=0; } for(checkPosition =0; checkPosition <10; checkPosition++){//Read bit fra 0-9
RFID_Slave3[checkPosition]=0; }
EEPROM_Save_Slaves();
RFID_SaveNextRead =false; }
RFID_Enable(true);//turns on the RFID reader
EmptySerialBuffer();//erase the buffer
Serial.println(""); }
i++;//used in the beginning to write to each bit in the buffer } } //Go to }
void EmptySerialBuffer(){//replaces all bits in the buffer with zeros while(Serial.available()){ Serial.read();} for(i2 =0; i2 <= i; i2++){
buffer[i2]=0; }
i =0; }
void PreLock(){
servoLock.attach(servoPin);// attaches the servo on pin 3 to the servo object
servoLock.write(LockedPos);// tell servo to go to position in variable 'LockedPos'
delay(250);// waits 1s for the servo to reach the position
servoLock.detach();//detaches the servo, so it's not using power
DoorLocked =true;//the door is locked }
void Unlock(byte speedDelay){ int pos;
servoLock.attach(servoPin);// attaches the servo on pin 3 to the servo object for(pos = LockedPos; pos < UnlockedPos; pos +=1)// goes from 10 degrees to 110 degrees {// in steps of 1 degree
servoLock.write(pos);// tell servo to go to position in variable 'pos'
delay(speedDelay);// waits 5ms for the servo to reach the position }
servoLock.detach();//detaches the servo, so it's not using power
DoorLocked =false;//the door is unlocked }
void Lock(byte speedDelay){ int pos;
servoLock.attach(servoPin);// attaches the servo on pin 3 to the servo object for(pos = UnlockedPos; pos > LockedPos; pos -=1)// goes from 110 degrees to 10 degrees {// in steps of 1 degree
servoLock.write(pos);// tell servo to go to position in variable 'pos'
delay(speedDelay);// waits 5ms for the servo to reach the position }
servoLock.detach();//detaches the servo, so it's not using power
DoorLocked =true;//the door is locked }
void RFID_Enable(boolean enabled){ if(enabled ==true){
digitalWrite(RFID_Enabled_Pin, LOW);//enables the RDIF reader and turns on the diode on the arduino
digitalWrite(13, HIGH); }else{//disables the RDIF reader and turns off the diode on the arduino
digitalWrite(RFID_Enabled_Pin, HIGH);
digitalWrite(13, LOW); } }
void EEPROM_Read_Slaves(){
byte EPROMaddr; for(EPROMaddr =0; EPROMaddr <10; EPROMaddr++){//Read bit fra 0-9
RFID_Slave1[EPROMaddr]= EEPROM.read(EPROMaddr); } for(EPROMaddr =10; EPROMaddr <20; EPROMaddr++){//Read bit fra 0-9
RFID_Slave2[EPROMaddr-10]= EEPROM.read(EPROMaddr); } for(EPROMaddr =20; EPROMaddr <30; EPROMaddr++){//Read bit fra 0-9
RFID_Slave3[EPROMaddr-20]= EEPROM.read(EPROMaddr); } }
void EEPROM_Save_Slaves(){
byte EPROMaddr; for(EPROMaddr =0; EPROMaddr <10; EPROMaddr++){//Read bit fra 0-9
EEPROM.write(EPROMaddr, RFID_Slave1[EPROMaddr]); } for(EPROMaddr =10; EPROMaddr <20; EPROMaddr++){//Read bit fra 0-9
EEPROM.write(EPROMaddr, RFID_Slave2[EPROMaddr-10]); } for(EPROMaddr =20; EPROMaddr <30; EPROMaddr++){//Read bit fra 0-9
EEPROM.write(EPROMaddr, RFID_Slave3[EPROMaddr-20]); } }
As I promised in my previous post, I would show you how to get USB Host working on the FEZ Panda.
FEZ Panda - USB Host Cable
When I first glanced at the LPC2387 datasheet (the ARM on the Panda), I notice that it actually supported USB Host. Then I thought why it wasn’t possible to use USB Host on the Panda, and I quickly found out that it was because it required some hardware modifications.
USB Cable Wiring
The difference in the hardware between USB Client and USB Host is that the Host is powering the Client, and the Panda had a protection diode so no power would go “out” the USB port. Another thing to notice is that USB Host requires two 15K resistors to pull D+ and D- to ground.
FEZ Panda - USB Host cable wiring
SMD solution
So how did I do it? I didn’t want to modify the FEZ Panda board, as the USB port would then be a permanent USB Host port. Instead I thought it would be nice just to have a cable for the USB Host thing, which should include the two resistors, and a power wire for the +5V power supply.
The first image in this post is my cable, and the second image shows the connections, where there is soldered two 15K SMD 0805 resistors inside. This took a long time to make because it was so small, and SMD resistors can’t handle much force. On a longer term basis it would be better to make an adapter PCB instead.
USB Host cable Schematic
Above you can see the simple schematic of the changes that has to be made to the cable, including where to solder/connect the two 15K resistors.
Thru Hole solution
Instead of using SMD resistors I recommend you to use Thru Hole resistors, and they can handle a lot more force, and the joint will also be more reliable.
FEZ Panda - USB Host Cable
The assembly method is the same as with the SMD resistors. If you don’t have any 15K resistors in hand, we have also tested it with a 12K instead, and everything seems to be running fine with that too.
After I made the cable the last thing I had to do was to update the firmware on the FEZ Panda, as the firmware (USBizi) for the FEZ Panda, didn’t support USB Host until V4.1.5.0, though the processor did. After I uninstalled the old firmware/SDK, downloaded the new one, and installed it, I was ready to update the firmware. I just followed this simple Youtube guide:
After the firmware was updated, I connected a cable from the MODE pin to GND to enable Serial Port (COM1) debugging, as the USB port will now be used for USB Host functions.
Then I just followed the “USB Host – Mass Storage” chapter in the Beginners Guide to .NETMF.
To help you guys getting started, I used this code to test the USB Host function. The applications outputs which device is connected, and if a Mass Storage device is detected, the files- and folder tree is shown too.
// Hold a static reference in case the GC kicks in and disposes it // automatically, note that we only support one in this example! static PersistentStorage ps;
publicstaticvoid Main() {
UART.Open();
WriteSerial("Starting...");
// Subscribe to RemovableMedia events
RemovableMedia.Insert+= RemovableMedia_Insert;
RemovableMedia.Eject+= RemovableMedia_Eject;
// Subscribe to USB events
USBHostController.DeviceConnectedEvent+= DeviceConnectedEvent;
USBHostController.DeviceDisconnectedEvent+= DeviceDisconnectedEvent; // Sleep forever //Thread.Sleep(Timeout.Infinite);
switch(device.TYPE) { case USBH_DeviceType.HID:
USBDeviceType ="HID"; break; case USBH_DeviceType.Hub:
USBDeviceType ="Hub"; break; case USBH_DeviceType.Joystick:
USBDeviceType ="Joystick"; break; case USBH_DeviceType.Keyboard:
USBDeviceType ="Keyboard"; break; case USBH_DeviceType.MassStorage:
USBDeviceType ="Mass Storage"; break; case USBH_DeviceType.Mouse:
USBDeviceType ="Mouse"; break; case USBH_DeviceType.Printer:
USBDeviceType ="Printer"; break; case USBH_DeviceType.Serial_CDC: case USBH_DeviceType.Serial_FTDI: case USBH_DeviceType.Serial_Prolific: case USBH_DeviceType.Serial_Sierra_C885: case USBH_DeviceType.Serial_SiLabs:
USBDeviceType ="USB to Serial converter"; break; case USBH_DeviceType.Sierra_Installer:
USBDeviceType ="Sierra Installer"; break; case USBH_DeviceType.Unknown:
USBDeviceType ="Unknown"; break; default:
USBDeviceType ="Unknown"; break; }
staticvoid RemovableMedia_Insert(object sender, MediaEventArgs e) {
WriteSerial("Storage "" + e.Volume.RootDirectory + "" is inserted.");
WriteSerial("Getting files and folders:");
WriteSerial(""); if(e.Volume.IsFormatted) {
WriteFilesAndFolders(e.Volume.RootDirectory, e); } else {
WriteSerial("Storage is not formatted. Format on PC with FAT32/FAT16 first."); }
WriteSerial(""); }
staticstring[] files, filesSub; staticstring[] folders, foldersSub; staticvoid WriteFilesAndFolders(string path, MediaEventArgs e) {
files = Directory.GetFiles(path);
folders = Directory.GetDirectories(path);
WriteSerial("Files available on "+ path +":"); for(int i =0; i < files.Length; i++)
WriteSerial(" "+ files[i]);
WriteSerial("Folders available on "+ path +":"); for(int i =0; i < folders.Length; i++) {
WriteSerial(" "+ folders[i]);
WriteSerial("");
WriteSubFilesAndFolders(folders[i], e); } }
staticvoid WriteSubFilesAndFolders(string path, MediaEventArgs e) {
filesSub = Directory.GetFiles(path);
foldersSub = Directory.GetDirectories(path);
WriteSerial("Files available on "+ path +":"); for(int i =0; i < filesSub.Length; i++)
WriteSerial(" "+ filesSub[i]);
WriteSerial("Folders available on "+ path +":"); for(int i =0; i < foldersSub.Length; i++) {
WriteSerial(" "+ foldersSub[i]);
WriteSerial("");
WriteSubFilesAndFolders(foldersSub[i], e); } }
staticvoid WriteTestFile(string dataToWrite) { if(VolumeInfo.GetVolumes().Length<1)return; // Assume one storage device is available, // access it through NETMF string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
FileStream FileHandle =new FileStream(rootDirectory +@"\hello.txt", FileMode.Create); byte[] data = Encoding.UTF8.GetBytes(dataToWrite); // write the data and close the file
FileHandle.Write(data, 0, data.Length);
FileHandle.Close(); }
staticstring ReadTestFile() { if(VolumeInfo.GetVolumes().Length<1)return"No Mass Storage found!"; // Assume one storage device is available, // access it through NETMF string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory; if(!new FileInfo(rootDirectory +@"\hello.txt").Exists)return"File not found!";
FileStream FileHandle =new FileStream(rootDirectory +@"\hello.txt", FileMode.Open, FileAccess.Read); byte[] data =newbyte[100]; // write the data and close the file int read_count = FileHandle.Read(data, 0, data.Length);
FileHandle.Close(); //Debug.Print("The size of data we read is: " + read_count.ToString()); //Debug.Print("Data from file:"); //Debug.Print(new string(Encoding.UTF8.GetChars(data), 0, read_count)); returnnewstring(Encoding.UTF8.GetChars(data), 0, read_count); } staticvoid WriteSerial(string StringToWrite) { // convert the string to bytes byte[] buffer = Encoding.UTF8.GetBytes(StringToWrite +"\r\n"); // send the bytes on the serial port
UART.Write(buffer, 0, buffer.Length); } } }
This video is just an example of what you can use the USB-host functionality for:
Update
Kristian has succesfully connected the PS3 Controller to the FEZ Panda, for more information, take a look at his post.
The FEZ Panda is an ARM7 board, in an Arduino-form-factor, running the .NET Micro Framework. This makes it possible to develop the applications inside Visual Studio using C#. Debugging is also done thru Visual Studio and in my opinion it is very easy to get started.
The great thing about the FEZ Panda, compared to a normal Arduino is the features and the speed.
FEZ Panda features
Instead of a simple 8-bit processor, this is a 32-bit ARM processor clocked at 72MHz. This makes it a monster compared to the Arduino series! The board contains 4 COM ports, 2 SPI ports, real SD interface, a lot of PWMs, Analog inputs (ADC), Analog outputs (DAC), I2C, CAN, USB Client, USB Host – you name it.
Inside the ARM processor, the .NET Micro Framework is running, which includes a FAT filesystem stack. This makes it possible to connect FAT formatted SD card or USB memory sticks to the board.
With this board you get a lot of power and a growing community. There is a lot of examples included, and many more can be downloaded from the .NET Micro Framework projects page. GHI Electronics, who is the manufactor of this board, has other boards running .NETMF too. They have a bigger version of this FEZ Panda, but still in the Arduino-form-factor, called FEZ Domino
This board is almost twice as expensive, but in my opinion you don’t get twice as much – only a USB Host connecter and an SD card slot. You actually have far less IO’s on the FEZ Domino than on the FEZ Panda, which I think is bad. So I recommend you to try the FEZ Panda!
In my next post I will show how to use the “hidden” USB Host function on the FEZ Panda – as it isn’t stated as supported on the product page, the ARM processor support both USB Host and Client. The only thing it requires, is a little USB Cable tweaking and a firmware update of the ARM to the latest firmware from GHI Electronics.
I posted this video on Youtube long time ago, but I forgot to write about it on my blog.
In the video I demonstrate how the Basys2 board, with a Spartan-3E 100K, can be used to generate a VGA signal.
I also show my bouncing ball application.
You can download the Xilinx project files here, including the VHDL files and User Constraint File for the Basys2 board.
The LatticeMico32 is an open source soft core processor provided by Lattice. The Lattice system makes a complete set of Verilog files, which can be ported to any FPGA. I decided to port it to the Xilinx series.
The example in the guide just blinks some LEDs, but it is not just LED blinking made with Verilog or VHDL coding, it’s made with C-coding inside an Eclipse enviroment, then compiled to the LatticeMico32. In the video above I show my first example and experience with the LM32 on the Spartan 6 FPGA.
Xilinx Spartan 6 XC6SLX9 to XC6SLX25 FPGA (I’ve got the XC6SLX25)
64 MByte DDR SDRAM
MicroSD socket
128 Kbit EEPROM memory
48MHz Clock for the FPGA (going out from the Cypress)
Spartan 6 module content
The first impression of the board is a nice design, it looks good and it feels good. The second great thing about the board, is that almost every pin on the FPGA has been brought out, and even also some of the Cypress microcontroller pins. It is also possible to customize the Cypress microcontroller firmware. There are also some connections between the FPGA and the Cypress microcontroller, which makes it possible to develop applications that uses both the FPGA and the Cypress microcontroller.
As the Cypress microntroller has a USB capability, it is also used to upload designs to the FPGA, but it can also be used in your own applications.
When I first got the board it was kind of difficult getting started. Though the ZTEX website contains a lot of documents, schematics and layout, and they have a nice Wiki, I kind of missed an easy “Getting Started” guide.
But after reading the Wiki a couple of times, I downloaded their Firmware/SDK package and got their FWLoader running. The FWLoader is a Java application used to communicate with the Onboard Cypress microcontroller over USB.
To communicate with the Cypress microcontroller, you can use their FWLoader, found in their ZTEX EZ-USB SDK. To begin with, you have to upload the firmware for the Cypress microcontroller, which takes care of programming the FPGA. To do so, you have to copy “standalone.ihx” to the java folder (inside the SDK), and then afterwards execute the following command.
After executing this command, it was now possible to communicate with the Cypress microcontroller using the commands explained on their FWLoader Wiki page. I was able to upload my first bitfile to the FPGA using the following command.
java -cp FWLoader.jar FWLoader -uf <bit-fil>
In the video above you can see my first experience with the board, getting a couple of LEDs to blink. I’ve used the 48MHz Clock, prescaled it, and made a simple counter – it worked 🙂
So in total, it wasn’t that difficult to get it running. The things that was difficult, was figuring out how their FWLoader worked, and how I should upload new designs. Though their Wiki was a great help!
As the Spartan 6 has a lot of power, I am sure that this will be a well-used board, and I can already imagine getting the LatticeMico32, a 32-bit open soft core processor, to work on this.
For a couple of weeks ago some of you might have noticed that I had published a video about me destroying an electronics board.
This was done as a part of an NXP contest, where you could get a free LPCXpresso board, by showing them how you would break your 8-/16-bit habbit!
LPCXpresso Board
Today I then recieved the board and it looks pretty promising. Can’t wait to get started testing it! If you haven’t seen the video, you can watch it here:
I haven’t been posting in a long time, but I just haven’t had time to do it. I have been playing around with many different projects, both Freelance projects and my own projects.
Then I thought it would be nice to post some pictures and a video about my latest project about my Hacked/Modded DACKO RC Car.
The WiFi Controlled RC Car
As you can see on the image, I have disassembled the car and then found the controller module. Then I found an RF chip/IC on the board (RX2), and I was lucky to be able to find the datasheet of that.
Closeup of the WiFi Controlled RC Car
Then I soldered some wires to the specific pins for the motor driver circuit, one pin for each direction (forward, backward, left and right).
Then I connected theese wires to the Arduino, made a test program where the Forward and Backward pins was PWM controlled, making it possible to change speed. The left and right pin should just be driven high to turn the wheels.
After some testing, I attached the WiShield WiFi module from Asynclabs, and then I started programming a socket application for the Arduino. I thought it would be fastest and easiest to use the TCP protocol directly, than serving a webpage. After some tests with Hercules SETUP Utility I made myself a controller application in Visual Basic .NET – and off we go!
After a couple of inquiries from people asking for the Arduino and Visual Basic .NET code for this project, I’ve decided to upload it.
You can download the complete project including the used WiShield library, the Arduino code and the VB.NET code, here: WiFi Controlled Car Project
Recent Comments