1. Arduino Image Sensor
  2. Arduino To Arduino I2c
  3. Arduino Image Library
  4. Arduino To Arduino Wireless Communication

Most 8-bit AVRs in the wild (including this project's Arduino Nano) run at a default maximum 16 MHz. That's 16,000,000 calculations per second... a respectable number for most embedded applications.

The VGA video standard, which is the default 'we-can-always-fallback-to-this' industry standard is 640 pixels wide by 480 pixels tall by 60 frames per second.

Arduino Image Sensor

Copy the code below to a new Arduino sketch, then copy the above-generated HEX code just above the void Setup function in the Arduino code.so it will look like this. Now select the board and port from the tools menu and upload the code, that's it now Our OLED will start displaying the image. Arduino Stack Exchange is a question and answer site for developers of open-source hardware and software that is compatible with Arduino. It only takes a minute to sign up. Sign up to join this community. Anybody can ask a question Anybody can answer The best answers are. To load the graphics into our Arduino code, we will need to convert the bitmap image into byte arrays. To do this, we will use the LCD assistant software. LCD Assistant is a free and easy to use software that converts bitmap images into a data array which can then be used in C programming language based firmware for any micro-controller. Learn how to make a door lock system using password with keypad and electromagnetic lock. When the door is unlocked by a correct password, It keeps the door unlocked for 20 seconds, and then automatically lock the door again. The Arduino code supports multiple passwords. The detail instruction, code, wiring diagram, video tutorial, line-by-line code explanation are provided to help you quickly.

This standard requires pixels to be clocked out at 25.175 MHz:

25,175,000 > 16,000,000.

Generating Full VGA Video from an Arduino

Clock speed was just one of the barriers to pulling off this (silly) project.

And with the clock doubling hack I documented, higher resolution is possible without overclocking the Arduino. You could reach roughly 800x600 in 4 bit color with 16MHz parts, and 1024x768 in 4 bit color for 20 MHz clocked parts.

(If you're willing to drop to 2 or 1 bit color and spend a ton on ICs that can handle even faster clocks, you can hit HD resolutions. You'll run into financial constraints before you max out on the technical side)

What Was the Previous Maximum VGA Resolution on an Arduino?

With tight coding you can achieve around 512 pixels wide on a 20 Mhz or ~400 pixels wide on a 16 MHz part. That math is simple: (20/25.175 * 640) or (16/25.175) * 640 at one pixel per clock cycle.

My goal was to produce 'full screen' Arduino VGA video. Color too, to spike the football.

A note on video technology: people have hacked color NTSC video out of Arduinos, but generally have only done so by changing the clock to 14.31818 MHz crystals. Television compatibility is great, but I targeted VGA and its simple, discrete outputs for red, green, and blue all while keeping the stock 16 MHz clock.

And what were your goals?

My requirements for this project:

  • Full width video, (>= 640 pixels wide) from an Arduino
  • Color
  • Use only parts I have on hand
  • No reprogrammable logic (FPGA/CPLD/GAL/PAL/PLA/Whatever else is out there)
  • No overclocking!

Bill of Materials and Schematic for 640x480 VGA on an Arduino

I used 6 ICs, 10 resistors, one VGA port and a bunch of jumper wire in my original build. The first four parts are for the clock circuit I discussed last week. And yes, I mix logic families:

  • HD74LS04P – Not Gate. Used as Delay
  • HD74LS08P – And Gate. XOR half
  • HD74LS32P – Or Gate. XOR other half
  • SN74F10N – Fast 3 Input Nand Gates. Clean up the ugly clock from the hacked XOR, also used as Inverter
  • DM74LS244N - 3 State Buffer/Line Driver/Line Receiver. Control which pixel of the two is on the output bus.
  • SN74LS373N - 8 D Type Latches. Our digital sampler/output to resistors and sync.
  • VGA Port - See Nick Gammon's site for how to wire this.
  • Resistors ~68 Ohm. Sync signals.
  • Resistors ~470 Ohm. R/G/B signals.

Substitutions are fine, just keep the propagation delay of the parts under 32 ns so you can latch in time (if you do my clock hack, probably 20ns due to the weird duty cycle) or so.

A Note/Disclaimer: I make no warranty that this is absolutely correct, and that I even transposed it correctly from my working copy. I may have transposed incorrectly, don't even trust the picture 100%. Before you turn this on, check my connections are accurate, your connections are correct and you understand what's happening.
DQYDJ won't be held responsible if you break any equipment using this circuit!

An Updated, Improved Bill of Materials

I bought some components and eliminated two pieces of silicon from the original build. If you build this smaller version, the code itself doesn't change.

(Note: It's better to start with a 32 MHz oscillator and divide the clock by 2 to drive the Arduino than to use my clock doubling hack. That would cut your IC count down by 2-3!)

Be sure to add the 470 ohm resistors for Red/Green/Blue and the 68 ohm resistors for VSYNC/HSYNC - they aren't pictured in the schematic!

  • 470 ohm resistors for R/G/B
  • 68 ohm resistors for Hsync/Vsync
  • 74LS04P - delay circuit for making the 32 MHz clock
  • 74F257N - Multiplexer, replaces the previous latch/transceiver
  • 74F86N - XOR Gate, replaces the one I built above from And/Or/Not gates (Missed label - it's IC2)

How Did You Achieve 640x480 with a 16 MHz Part?

First, I'd like to thank three folks in particular for inspiring this project. Nick Gammon is the first - his VGA library was the start point for this successful project, and this demo requires his Timing library. His timers greatly simplified the interrupt writing necessary for this project. His wiring diagrams and initial code-base were invaluable for sanity checking my early prototypes.

Second, thanks is owed to Henning Karlsen, who had great 16x16 fonts available for easy use in Microcontroller projects. Please checkout his projects, especially his UTFT related projects with resources for serial displays. My message generator uses one of his fonts.

Third, to Linus Akesson (a.k.a. lft) who bitbanged VGA color video out of a similar part back in 2008. (His site, here). Inspirational!

How to achieve a pixel rate faster than a base clock

At the most basic level, I treated the 8-bit microcontroller as two interleaving 4 bit microcontrollers by dividing its output into two logical parts per cycle.

For this demo, I had two disparate sets of Reds, Greens and Blues, laid out like you see nearby. Here is the pin layout from my Arduino:

Pin D7: Red 1
Pin D6: Green 1
Pin D5: Blue 1
Pin D4: Red 2
Pin D3: HSync
Pin D2: Green 2
Pin D1 (Tx): N/C
Pin D0 (Rx): Blue 2

... that's all on the AVR's Port D.

Once I had the 32 MHz clock I discussed in my clock doubling hack post, the project came together quickly. The 32 MHz clock goes to the Latch Enable Pin (11) of the LS373. Enable is tied to ground (always on), in effect latching to the 373 outputs to whatever value happens to be presented every 32 ns.

The 244N uses the stock 16 MHz clock, plus the clock 180 degrees out of phase with itself connected to both enables.

Out of phase means when one clock is high, the other is low. Thus, only one pixel is allowed through to the 373N... and that's how you present ~810 samples to the monitor when you previously could only do half that.

I cleared 640 samples with plenty of breathing room.

Simplifying the Video Circuit

If you give up color fidelity (the latch), you can use the clock and an inverted clock into the enables on the DM74LS244N - 2 chips.

Some folks will be bothered by the mild amount of chip inflation on the board. You could achieve a 32MHz clock with an external crystal, and divide it to a 16MHz clock for the Arduino (thus eliminating 3 ICs).

I've thought about it a bit, and I can't come up with a way to clock out more than one pixel per clock at 25 MHz without some kind of active component assistance. (But please contact me if you have a way!)

Can you eliminate the integrated circuits?

Yes, you could get rid of the latch and the buffer and go to a transistor only setup.

I tried to demo this with common NPNs and PNPs - 2222s and 3904s and 3906s - but they don't have the switching speed necessary. I don't have any higher speed transistors, but I'd love if someone tried to do this with something faster. I'm thinking:

2 transistors per bus for R/G/B, one active high and one active low, then the 470 ohm resistors into the VGA port.

If you pull that off you can kill the clock circuit completely since we'll be clocking at 32 MHz a second - low clock AND high clock assuming your transistors are fast enough.

Could you do it with only passive components?

Hmm, perhaps by introducing some well timed delays with some fancy math and carefully selected components?

I don't know but tend to doubt it; my guess is you'll attenuate the signal too much for it to be useful to the monitor/TV. I believe some silicon/silicon equivalent will need to be in there. My guess is the minimum circuit is 6-8 transistors (PNP/NPNs) and some resistors.

(Please someone try to prove that wrong, though! It would make my day to see someone improve this design!)

Download and Run the Code

Sorry I buried this - I really wanted everyone to understand the challenges first. Usage is simple:

  1. Burn the CKOUT fuse on your AVR microcontroller - you need to Google how to do this; I did it on a Mac by modifying 'boards.txt' and choosing 'Burn Bootloader' in the Arduino IDE. This puts the 16 MHz clock on pin D8 for the Nano.
  2. Next, grab Nick Gammon's Timer libraries.
  3. Third, download our code which runs the demo for the below video from here: Full640x480Video (zip)
  4. Wire up the schematic - make sure to find a way to get a doubled clock. We suggest a PLL or using a higher clock to begin with then dividing it for the Arduino to use. You can always do something like my clock doubler circuit, but please, please do it a better way.

Want to edit the text to something meaningful to you?

We made a script to make it easy to change the message displayed.

Click here to try it out - you just need to copy/paste the output into the fontLines16.h and fontLines16_2.h file and overwrite whatever is there to see the message transition.

(On a side note, that's Javascript compiling C which you'll copy & paste into the Arduino IDE running on Java which compiles to AVR assembly. 🤯)

Oh, of course, youdo this at your own risk. You should work through this on your own before trusting a random guy on the internet.

Since you've been waiting patiently, let's show the demo. We show off all 8 colors - each in rows 10px high, a '14 color' video rainbow made by mixing pixels, then some (ugly, 27% timing error) writing, then 10 lines of clocking out 640 pixelsof red/white mixed followed by blue/white mixed.

Full VGA on an Arduino Demo!

//www.youtube.com/embed/nmdvhgbsglQ?rel=0

Here's a tight crop so you can see that I'm actually generating a rainbow pattern at 640+ pixels wide (thanks for the healthy skepticism!):

If you still don't believe it's possible (you must be fun at parties!):

  1. Pop up the AVR 8-bit instruction listing.
  2. Search for the 'OUT' instruction. Note that it is a one clock instruction (16 MHz).
  3. Note that we treat each 'OUT' as 2 pixels using our external hardware (2x16MHz = 32 MHz, which is more than 25.175)

If you look at the assembly generated by our code it looks like a whole bunch of this:

  • // PORTD = B01010100; <--- 010 Green on one pixel, 110 Yellow on the one next to it
    4c2: 9b b9 out 0x0b, r25 ; 11

What Problems Did You Face with Arduino Full VGA?

Simple: samples, samples everywhere. Errors on top of errors!

First off, you've got the ugly clock and fluctuating duty cycle which is a consequence of the clock doubler hack. That's not even the main problem though.

The biggest issue is the fact that we're now clocking ''32 MHz'' into a standard calling for 25.175 MHz,. That wasn't a problem when folks were producing fewer pixels than 640 (you were guaranteed to have at least one of your pixels sampled). At 32 MHz you actually lose data with a digital monitor.

It's also far enough off that you get weird artifacts... look at that video again.

The error is huge: 32 / 25.175 =~ 27% error rate! It's safe to say there's an issue every 3-4 pixels: the monitor will sample while the latch is changing, or catch it during its propagation (low to high or high to low isn't instantly 5v or 0v) and render a color darker than we intended. In short: there shouldn't be vertical lines in the solid color horizontal bars in my video.

The third factor is technological - the monitor samples our jittery 32MHz hacked clock at 25.175 MHz to try to get 640x480.

The monitor itself? It's designed to be 1920x1080.

For this particular monitor, that's not an issue because I can get it to display double pixels at 1280x960 and letterbox the sides. But still, of course, blowing up pixels means you're zooming in on problems while the monitor is applying its own smoothing algorithms.

Arduino To Arduino I2c

So... errors on top of errors on top of errors.

How Could You Improve This Project?

First,...and simply: get a cleaner clock. Best would be to clock the Arduino at 12.5875 MHz. Second best, is to target a higher clock rate. That could be either with VESA 'non-standard standards' or other accepted timings (which aren't quite 640x480@60 - that's the gold standard). 640x480@73 fps, for example, needs a 31.5 MHz clock - that's only a 1.59% error. (Quite the cleanup from 27%.) You can also use VESA timings targeted at 32 MHz - YMMV, and you'll have to read the specs on your target monitor.

Second, you can improve color with a fourth bit of color for each pixel (remember, we divided our 8 bit processor into 2 - we're wasting a bit!). It's a nonstandard palette, but RGBI is doable. You just need to move the one sync pin.

Third, use external memory. The only practical use of this code is a silly hack for a web site (wait a second...). There isn't enough RAM to store discrete pixel information for 640x480, and self-modifying code on a Harvard Architecture uC which can only run from flash is... not smart.

Your Turn for Arduino VGA!

So, now, go have fun with the code and the schematic! It's released with the same license as Nick Gammon's VGA code.

Go out and make something more interesting than a poorly sampled digital signage display which shows a rainbow, then come back and share!

Arduino as ISP and Arduino Bootloaders

What makes an Arduino what it is? Many things, but one of the most important ones is the way every Arduino board is easily programmed with the Arduino Software (IDE). It is enough to connect it to the computer USB port and press the “Upload” icon to start a process that transfers your sketch into the Flash memory of the microcontroller.

On this page... (hide)

  • Use Arduino as ISP
  • Program the bootloader

The Bootloader

Arduino

The behaviour described above happens thanks to a special piece of code that is executed at every reset of the microcontroller and that looks for a sketch to be uploaded from the serial/USB port using a specific protocol and speed. If no connection is detected, the execution is passed to the code of your sketch.

This little (usually 512 bytes) piece of code is called the “Bootloader” and it is in an area of the memory of the microcontroller – at the end of the address space - that can’t be reprogrammed as a regular sketch and had been designed for such purpose.

The Memory Map of an ATmega328P


To program the bootloader and provide to the microcontroller the compatibility with the Arduino Software (IDE) you need to use an In-circuit Serial Programmer (ISP) that is the device that connects to a specific set of pins of the microcontroller to perform the programming of the whole flash memory of the microcontroller, bootloader included.The ISP programming procedure also includes the writing of fuses: a special set of bits that define how the microcontroller works under specific circumstances.

Use Arduino as ISP

The whole process of loading the bootloader code and burning properly the fuses to make an ATmega microcontroller an “Arduino” is managed by the Arduino Software (IDE): it provides a specific menu item and allows you to use a variety of programming devices. Among the programmers, the “Arduino as ISP” is the cheapest and most practical solution to burn a bootloader on another Arduino board with ATmega, 32U4 or ATtiny.


The programming process uses VCC, GND and four data pins. Three pins connect MISO, MOSI and SCK between the programming micro and the target micro, the fourth pin from the programming micro goes to the reset pin of the target.

How to wire your boards

The following table display on which pins the MOSI, MISO and SCK are broken out on the different Arduino boards:

Arduino / Genuino BoardMOSIMISOSCK Level
Uno or Duemilanove11 or ICSP-412 or ICSP-113 or ICSP-35V
Mega1280 or Mega256051 or ICSP-450 or ICSP-152 or ICSP-35V
LeonardoICSP-4ICSP-1ICSP-35V
DueICSP-4ICSP-1ICSP-33,3V
ZeroICSP-4ICSP-1ICSP-33,3V
10111 or ICSP-412 or ICSP-113 or ICSP-33,3V
MKR Family81093,3V

The SPI interface - and therefore these pins - is the interface used to program the AVR microcontrollers. Note that MISO, MOSI, and SCK are available in a consistent physical location on the ICSP header; this connector is used also by shields that rely on the SPI interface allowing the design of shields that work on every board.

On the Arduino UNO in the following image, we have highlighted in red the connections on the female strips; in yellow the ICSP connector that connects to the ATmega328P. Please note that the Rev.3 board has an ATMega 16U2 chip that manages the USB connection and also that chip can be reprogrammed via a dedicated connector labeled ICSP2, just above the ATMega 16U2 itself.


On some Arduino boards (see table above), pins MOSI, MISO and SCK are the same pins as digital pin 11, 12 and 13, respectively. That is why many tutorials instruct you to hook up the target to these pins. If you find this wiring more practical, have a define USE_OLD_STYLE_WIRING. This will work even when not using an Uno. (With the Uno board this is not needed).


In the picture above we are connecting two UNO boards for bootloader burning with the 'old style' connections: the top board is the Target, the bottom board is the Programmer. Note the yellow connection from D10 of the programmer to RESET of the target. On MKR family of boards, you can't use D10 for reset; we suggest D6 and you must remember to change the line 73 of the ArduinoISP sketch - #define RESET 10 - putting '6' insteat of 10.


This Arduino NANO is programmed through its ICSP connector with wires coming from D10-D13 of the programmer UNO board.


The Arduino MEGA above is programming an Arduino UNO connecting D51-D11, D50-D12, D52-D13, GND-GND, 5V-5V and D10 to RESET. This type of board needs a 10µF electrolytic capacitor connected to RESET and GND with the positive (long leg) connected to RESET. The capacitor has to be placed after the programmer board has been loaded with the ISP sketch.
The 10µF electrolytic capacitor connected to RESET and GND of the programming board is needed only for the boards that have an interface between the microcontroller and the computer's USB, like Mega, Uno, Mini, Nano. Boards like Leonardo, Esplora and Micro, with the USB directly managed by the microcontroller, don't need the capacitor.

About voltages

The Arduino family of boards includes 5V and 3.3V devices. When using an Arduino that is not 5V tolerant (Due, Zero, ...) as the programmer, make sure to not expose any of the programmer's pins to 5V. A simple way to accomplish this is to power the complete system (programmer and target) at 3V3.


In the above picture you see the wiring between a MKR1000 and a UNO. As described above, everything runs on 3.3V, taken from VCC and GND of the MKR1000 and sent to 5V and GND of the UNO. The same connection could be made to the ICSP of the UNO following the pinout explained in the page. We have used the same colors for the wires as in the other pictures to help you switch from the 'old wiring' to the ICSP connector with ease. Please note that the MKR family of boards share the same pinout, therefore you can use any MKR board as ISP programmer. If you use a MKR board as ISP programmer, remember to change the line 73 of the ArduinoISP defining the actual pin used on the MKR board to Reset the target (6 in the picture above).
Note: Please do not connect to USB or power supply the boards while you set up the connections and wires. We also suggest that you first program the Arduino used as ISP programmer before you proceed with the wiring to the target board.

Load the sketch

The Arduino that you will use as programmer needs a specific sketch. You find it under Examples > 11. ArduinoISP > ArduinoISP .


Going through the lines of the sketch you find a number of parameters that need to be set according to the target board. These parameters are, however, set by a specific file available for each bootloader/board supported by the Arduino Software (IDE). Other parameters are clearly explained by the comments and should be changed only if you know what you are doing.The sketch also supports three LEDs that give you a visual feedback about the programming process.


To upload the sketch to your Arduino board – the one that you will use as the programmer – you need to select board type and port, then you can proceed as usual.

Program the bootloader

If all the wires are set, you need to switch to the board type you want to program with the bootloader. This step is mandatory to select the proper bootloader code and the fuses configurations. The programming procedure checks the signature of the microcontroller before any writing action is taken, but many boards share the same microcontroller and each board has its own bootloader. The port remains the one of the ArduinoISP.
Choose “Burn bootloader” under tools and wait for the confirmation message in the lower part of the Arduino Software (IDE) interface. If you connected the LEDs you may follow the process visually.

Arduino


The Serial Programming Mode

The programming process manages the three SPI lines (MISO, MOSI and SCK) according to the standard SPI programming protocol, the same used to read and write SD memory cards. The only difference with memory cards is the lack of a CS (Chip select) pin. On our AVR microcontrollers we use the RESET pin that halts the execution of any sketch or bootloader and puts the microcontroller in a specific state where it listens to the commands arriving from the SPI interface. The very first command that the protocol requires is the one that enters the microcontroller in the Serial Programming Mode.

Once this specific mode is active, we can write and read all the microcontroller programmable areas: Flash, EEPROM and Fuses. At the end of the Flash memory, we have the bootloader code area, as highlighted in the image at the beginning of this article. The 'Burn Bootloader' procedure also sets properly the fuses of the microcontroller according to the design of the board. This is one of the reasons why you have to burn the bootloader selecting your exact board model in the list.

Technical aspects of programming

The open source software tool used to program the microcontroller is avrdude. The process goes through four steps: unlocking the bootloader section of the chip, setting the fuses on the chip, uploading the bootloader code to the chip, locking back the bootloader section of the chip.
The fuses are managed according to the preferences stored into each parameter file associated with the board, avoiding potential mistakes.
The management of fuses, usually a set of three bytes – low, high and extended -, is the most delicate aspect of the bootloader programming: a wrong fuse setting could brick the microcontroller and the board.Fuses define many aspects of the microcontroller’s functions like: selecting different clock sources and change how fast the chip runs, setting the minimum voltage required before the chip works (brownout), setting whether or not a bootloader is used, setting how much memory is allocated to the boot loader (from 256 to 2048 words – 512 to 4096 bytes),disabling reset or serial programming and stop EEPROM data being erased when uploading a new sketch.
Detailed description of the fuses can be found on the datasheet of each microcontroller.
Every setting has its own usage and it is logical to allow the developer to lock the chip and protect it from ISP programming, but it might happen to mistakenly set a fuse in the wrong way, locking you out of the programming process through the ISP interface. To recover the microcontroller, you have to rely on a High Voltage Serial Programmer that uses 12V to reset the fuses.

Recap: burn the Bootloader in 8 steps

  • Open the ArduinoISP firmware (in Examples) to your Arduino board.
  • Note for Arduino 1.0: you need to make one small change to the ArduinoISP code. Find the line in the heartbeat() function that says 'delay(40);' and change it to 'delay(20);'.
  • Select the items in the Tools > Board and Serial Port menus that correspond to the board you are using as the programmer (not the board being programmed).
  • Upload the ArduinoISP sketch.
  • Wire your Arduino boards..
  • Select the item in the Tools > Board menu that corresponds to the board on which you want to burn the bootloader (not the board that you're using as the programmer). See the board descriptions on the environment page for details.
  • Select the Arduino as ISP in the Tools>Programmer menu.
  • Use the Burn Bootloader command.


Arduino Image Library

See also

Arduino To Arduino Wireless Communication


Last revision: 2018/01/20 by SM