NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Support Forum » Question About Bootloaders
May 03, 2009 by Ethanal |
Suppose I wanted to make my own programmable device that uses the Atmega168 microcontroller, but wanted to make my own method of uploading the code to the chip. To be specific, I want to make an LED matrix that can be programmed with a GUI I will make, but want to make it sleek- attaches with only a USB cable. Would I need a special bootloader, if so what kind? Please tell me if I am not making myself clear. |
---|---|
May 03, 2009 by MacGyver |
Are you confusing code and data? To update a LED matrix you would be sending data to the MCU, not code. Using just the standard nerdkit you can send data to the MCU via the USB cable. If you are just sending data, then bootloader shouldn't affect things. Either way, the current bootloader that is used is "foodloader", which should be fine for using a USB cable to upload code, if that is what you need to do. |
May 04, 2009 by wayward |
Ethanal, if you're looking to reprogram the flash on the MCU, you can do that with just a bit of extra electronics: simpy pull PB0 and RESET low, which will reset the MCU and foodloader will go into reprogramming mode. Perhaps it's also worth checking the datasheet on how to perform a software reset that will cause foodloader to start listening for the new code. To answer your original question: I think foodloader will suit your purposes just fine, but you may have to change a few lines in it, if you need to throw in an extra check or to enable the 'E' command (exit bootloader, currently ignored by foodloader) so the MCU will start the program once it's been reprogrammed. Zoran |
May 07, 2009 by Ethanal |
I don't think I am confusing data and code. I was going to have the gui generate C code which it will send to the MCU. But now that you mention it, it might be more efficient to send it data. Is it possible to write a program where the MCU is taking in C code through the USB cable, which it executed within the program that is currently running? For example, the MCU is reading from the USB cable, and it receives code in the form of a string of text that sets pin 5 to high, so it sets pin 5 to high. If there is a more efficient way to do this, please tell me. |
May 08, 2009 by MacGyver |
AFAIK you would need another MCU or another way of both cutting the power and throwing the PB0 pin low to put the MCU into code loading mode. I'm still at a loss as to why you would be needing to update the code at all. If you want to set pin 5 high, then just send an ascii "5"digit or a binary 5 and have the MCU turn that into a pin command. Even if you aren't confusing code / data, it still seems like you have a fundamental misunderstanding about how most computer systems work, in that commands like "set pin 5 high" are sent as data and not code, as you can't just send plaintext C over when using the bootloader it has to already be compiled and sent in a certain way, which reboots the MCU in the process. Not to mention it uses a write cycle of the flash to lower the lifetime of your MCU, whereas when sent as data that shouldn't happen and you don't need to reboot it. A more efficient way would just be to send something like "5H" to the MCU and it would then set pin 5 high, or "5L" to set pin 5 low, "3H" to set pin 3 high, etc etc. This would be done without ever changing the code on the MCU. |
May 08, 2009 by wayward |
But just to be fair:
It is possible: you are asking about writing an embedded C interpreter. Fun, but complicated. |
May 09, 2009 by Ethanal |
Thanks everyone- your comments were very helpful. I probably do have a "fundamental misunderstanding about how most computer systems work" because I am very new to microcontrollers. I totally overlooked compiling the code. Oops. So, you are saying I should program the MCU to have a "vocabulary" where if it receives a certain string or binary number, it runs a certain function. What would be the best way of doing that? With a switch statement maybe? Thanks again to everyone who has contributed to this string so far. P.S. Is there any quick and easy way to convert decimal numbers to binary numbers via code without a bunch of arithmetic? |
May 09, 2009 by Ethanal |
Is it possible that something like what's at this link be used with this project so I don't have to use the serial adapter and the USB programming cable? |
May 10, 2009 by MacGyver |
"P.S. Is there any quick and easy way to convert decimal numbers to binary numbers via code without a bunch of arithmetic?" Yes and no, in reality there is no "conversion" being done as all numbers(decimal, hex, octal, binary) are represented as binary inside the code. Whether you store "0xA3" or "0243" or "163", they are all represented as binary "10100011" internally. Regarding the "USB only" link, the entire "serial to USB" converter is made much bulkier for clarity, if you wire the pins from the USB directly to the different parts it could be shrunk down by a great deal. Regarding the code you should look at the LED Marquee project as it seems to do what you want, you send it "Hello World!" and it operates the LED matrix to print that to the screen. If you want finer control than an ascii dictionary, then just copy the LED Marquee code but replace the ascii dictionary with a series of commands for each individual LED. But yeah, a switch statement or if/else structure would work for that part. |
May 12, 2009 by Ethanal |
Thanks. |
May 13, 2009 by MacGyver |
0xA3 is the hex representation, so with A being decimal of 10 A = 1010 3 = 0011 So 10100011 in binary In C a leading 0 is used for octal, so octal 0243: 28^2 = 128 base 10 or 1000 0000 binary 48^1 = 32 base 10 or 0010 0000 binary 3*8^0 = 3 base 10 or 0000 0011 binary So 128+32+3 = 163, you perform and on those 3 values giving you 10100011 binary or 163. 163 is the base 10 representation so as above converts to 10100011 binary. What I was getting at, is that if you bit shift any form of these such as: val = (0xA3 >> 4) & 1; val = (0243 >> 4) & 1; val = (163 >> 4) & 1; You are going to get the same value because internally they are all binary, so there is no need to "convert" them. for instance: printf("%d %d %d",0xA3, 0243, 163); should always print "163 163 163", just as: printf("%x %x %x",0xA3, 0243, 163); should always print "a3 a3 a3". I hope this makes things clearer on that end. Regarding the VUsb thing, it may be the best for you as I don't know your project requirements, I was just pointing out since you mentioned "sleek" as something you wanted, that the current serial -> usb could be made much smaller as basically you are running through the commercial usb -> serial port converter then into nerdkits circuit. If you wanted it "sleek", then much of the bulk could be removed by hacking out the parts and rewiring them. If you are opposed to that or learning what goes into converting usb into serial appropriate for the MCU uart(and building it), then VUsb might be best. Not sure what your requirements are so can't really answer further, just pointing out that much of the bulk is to make the kit user-friendly, its not required by the hardware itself. |
May 19, 2009 by mrobbins (NerdKits Staff) |
Hi Ethanal, If you are trying to make an LED array that you can control with a PC present, you don't really need to reprogram the microcontroller's flash. As suggested above, you can just take that data over the serial port and do something with it as the program is running. However, if you want to make an LED array that you can connect to a PC, program a message, and then have it remember that message after being disconnected and power-cycled, you have two options. One is to change the program code, like you do every time you compile and use "avrdude". But another way to do it is to use the ATmega168's on-chip 512-byte EEPROM, which is made just for cases like this where you want to store settings, etc. Your program could write to and read from this memory area with commands like:
See also the eeprom.h documentation. Hope that helps! Mike |
May 19, 2009 by Ethanal |
Mike, Oh, wow! This whole process would have been so much easier had I known that the chip has an EEPROM! I had no idea. Thanks a bunch. This will help with future projects too! Ethan P.S. If some messages prove to be too big for the EEPROM, could I use an SD card or something? |
November 25, 2009 by pbfy0 |
I think you could use an SD card over SPI, but I haven't tried it. |
November 25, 2009 by pbfy0 |
here is a SD lib that I took from here and modified to read and write 512 byte blocks. I think the code explains itself pretty well, but add a post to the forum if it's confusing. The read/write functions are write512block(char block[512], uint32_t segment) and get512block(char array, uint32_t segment). The char array in get512block is the array to put the bytes into, and the uint32_t segment is where in the SD card to put it. The array should be uint8_t with 512 elements. char block[512] is the array to write from, also uint8_t with 512 elements. Untested, but should work. |
Please log in to post a reply.
Did you know that Pulse Width Modulation (PWM) can be used to control the speed of a motor digitally? Learn more...
|