Nano V3.0 Microcontroller

Behind the 5th doors of this advent calendar hides the Nano V3 micro controller. One can call him the little brother of the Uno micro controller. It can be used to implement projects in which the smaller dimension is an important requirement. It basically offers everything you need for evaluating sensors or controlling actuators. Important details can be found in the Data sheet and in the pinout which are also linked in the AZ Shop. You should have both at hand when you start a project.

The most important information is that the 13 digital Pins can be used as inputs and outputs. In addition, eight analog Pins with Analog-to-Digital converter are available, which can also be used as digital Pins. Communication with other devices or components takes place via I2C (A4 and A5), USART (D0 and D1) or SPI interface (D10, D11 and D12). Pins D2 and D3 can be used for external interrupts.

In the advent contribution of 03.12. it was already shown how to install the Arduino IDE and load the Blink example on the Uno. This works exactly the same for the Nano Micro controller. For the Ch340 Chip that is on the Board, you may need to install a Driver so that the Nano V3 Microcontroller is recognized as a virtual COM Port (the linked page is in Chinese language. Press the big blue Button. The ZIP file contains the driver. Select the right one for a 32-or 64-Bit System).

Micro-controller connecting

Then, when you connect the Nano, select the Arduino Nano under Tools->Board. As processor the ATmega328P (Old Bootloader). In the AZ Blogs you will find a Contribution by Albert Vu, who describes how to "flash" the Bootloader so that you no longer have to choose the old Bootloader. A COM Port should now appear under the menu item" Port". The number behind it varies.

For testing, load the example Blink onto the micro controller (Sketch - > upload, or Ctrl + U). On the board there is an Onboard LED, which should blink after the successful Upload (the LED is connected to Pin D13 by the way. The Constant LED_BUILTIN refers to this Pin).

Sensors or changeable resistors (potentiometers, also Poti) provide a voltage that can be measured at the analog inputs. On the Nano Board, Analog-to-Digital converters are integrated, which convert these physical values. With the function analogRead (PIN number) returns a value between 0 and 1023. if you want to change this range, e.g. if you need 0 to 255, you can use the function map(value, fromLow, fromhigh, toLow, tohigh) use (for more information, see here).




Input value (e.g. off analogRead())


lower source range (here 0)


upper source range (here 1023)


lower target range (here 0)


upper target range (here 255)

Analog Input

The Arduino IDE and built-in libraries provide plenty of sample ketches. So also for the analog Pins. Open the Sketch in the menu File -> examples -> 03. Analog input. This is a modified Blink example in which a Potentiometer regulates the flashing speed. Connect everything as shown in the following Fritzing and download the example on the Nano:

The input values 0 to 1023 are passed here directly as a value for the pause. The specification in the delay()-Function is specified in milliseconds. So we reach pauses between 0 and 1023 ms. but if we want to set pauses between 1 and 5 seconds (1000 and 5000 ms), then here comes the above mentioned map()- Feature in the game.

The outer connections of the potentiometer are connected to 5V and GND, the middle contact (grinder) to A0. This is how it is defined in the example sketch. The ledPin 13 is (as mentioned above) the contact to the Onboard LED. If you run the program on the Nano, you can use the potentiometer to adjust the pause for switching between on and off, thus increasing or decreasing the flashing pauses.

After the line for reading, add the following line:

// read the value from the sensor:
sensorValue = analogRead(sensorPin);
sensorValue = map(sensorValue, 0, 1023, 1000, 5000);

This overwrites the previously read value, which is now converted (scaled) to the new value range. The breaks should be much longer.

Note: the function delay() provides real breaks in the program flow. Therefore, the change to the poti will only take effect when the break is over. To change this, a non-blocking program would be better suited. See the example sketch under 02. Digital - > BlinkWithoutDelay. There it is shown how the switching of the LED is realized with time measurements. With the poti you would then have to change the interval.

The trick with the dimmed LEDs

As a rule, the brightness of an LED cannot be changed via the voltage, as is the case with incandescent lamps. You use a trick that ensures that the LED is only switched on and off for a very short time. This happens so quickly that it looks to our eye as if the LED is darker the shorter the on and off time. We can change the previous Sketch a bit to see the effect. Instead of delay() we use delayMicroseconds() for the breaks, and we set the target value to change the range of 1000 and 5000 in the 0 and 10. This can be changed by Turning the potentiometer the brightness of the Onboard LED.

However, if you want to do this correctly, you use the so-called Pulse Width Modulation (PWM). On the Data sheet you can see which Pins are capable of this. Often a Tilde (a lying S) is printed on the Board in addition to the PIN numbers to identify the PWM Pins. Connect an LED (do not forget the resistor) to Pin 9 and load the example "Fading" under file->examples->3.Analog on the Nano. The LED should now pulsate.

To control the external LED with the potentiometer, we add both Sketches together:

ledPin = 9;    // Led connected to digital pin 9
int sensorPin = A0; / / select the input pin for the potentiometer
int fadevalue = 0; // variable to store the value coming from the sensor

void setup() {}

void loop() {
fadevalue = analogRead(sensorPin);
fadeValue = map(fadevalue, 0, 1023, 0, 255);
analogWrite (ledPin, fadeValue);

If you prefer a minimized Code, then the shortened looks like this:

void setup() {}

void loop() {
analogWrite (9, map (analogRead(A0), 0, 1023, 0, 255));

The functionality remains the same.

Digital Input

Often we need buttons as input option. Be it to start or stop a process, or other functions. Here the digital pins can be used relatively easily. However, care must be taken that in this case the buttons do not simply close circuits. For this reason, Pullup or Pulldown resistors must be used to clearly define the states on the Pins. On the Nano, Pullup resistors are integrated on each digital Pin. These are setup() enabled when the respective Pin is initialized as input:

pinMode (buttonPin, INPUT_PULLUP);

However, in this case is the entrance active low. This means that the low state of the pin is now active, i.e. on. In contrast, HIGH is the off state. The example sketch "DigitalInputPullup" under file - > examples - >2. Digital shows again how it works. The button is connected between pin D2 and GND.

You can also build this with external resistors. Then you do not need the internal resistance. In the example sketch "Button", the information describes the circuit for a Pull-down resistor and explains how digital inputs are used. The circuit diagram looks like this:

Instead of using a button, you can also simply hold the ends of two plug-in bridges or cables together. For example, if you want to build an alarm system on Windows or doors, simply use flat metal contacts that are connected to the pins. This is also possible.

One Problem with buttons is that they"bounce". If you are surprised that it sometimes looks as if you have pressed the button several times, this is due to this physical effect. You can solve this with Capacitors, or in Software. The Sketch "Debounce" is an example of such a solution. Basically, it is about detecting a push of a button and then ignoring the button for a short time. Another approach would be to check several times whether the Button is still pressed. Then you are sure that it was not a random signal and pass it on to the program.

External Voltage Sources

Often you want to use your project independently of a Computer. This is only necessary for uploading the sketch to the micro controller. If you are using a battery or a power supply, then you do not need the PC. The Nano can be supplied with voltage via three connections. First from the PC, via the Mini USB port. Second, you can connect there a USB plug power supply or a power bank.

In addition, the Nano has a VIN connection (Voltage Input). There you can apply a voltage between 7V and 12V. Either with a laboratory power supply, a 9V Block, a battery pack with several AA batteries, or a LiPo battery with voltage regulator (LiPo batteries usually deliver less than 5V, so the voltage needs to be transformed).

In the first little door of the AZ advent calendar there was the Breadboard Kit, which contains a power supply module. This provides a voltage supply of 3.3 V or 5V. These voltages can be used for sensors and input pins. To connect more than 5V to the input pins should be avoided, this could damage the Nano.

Display and input

Finally, the possibility of sending to and receiving data from the Serial Monitor of the IDE should be mentioned. This is sometimes required for debugging. The serial communication between Nano micro controller and PC is used for this. In setup() it is initialized as follows:


The value in the bracket is the baud rate (i.e. the transmission speed). In the Arduino IDE, in the Tools menu, you can open either the serial Monitor or the serial Plotter. The Plotter is quite suitable for sensor data to detect tendencies. The serial Monitor outputs values or texts. It is important that the baud rate, which is set at the bottom right of the Monitor, is set with the value in the initialization in the setup() match that.

Now you can insert screen outputs at any point in your source code with:

Serial.println (value); // Variable value is output with line break
Serial.print (value); // Variable value is output without line break
Serial.println (value, HEX); // Variable value is output hexadecimal
Serial.println (value, BIN); // Variable value is output binaer
Serial.println("Merry Christmas!");      // Text output

This means that it is not possible to output multiple variables simultaneously with one call. Either you use multiple calls of Serial.print(), or you first put the Text together in a string variable, which you then output.

Note: Sprintf does not support floating point numbers (with %f) on an AVR board in the Arduino IDE

double kommaZahl_A = 12.345678;
double kommaZahl_B = 98.765432;
char kommaZahl_A_str[10];
char kommaZahl_B_str[10];
char result buffer[10];
char output buffer[25];
void setup() {
  // initialize:
  // ***** single output *****
Serial.print(kommaZahl_A, 2); // two decimal places
Serial.print(" + ");
Serial.print(kommaZahl_B, 2); // two decimal places
Serial.print(" = ");
  // with output of the calculation with four decimal places:
Serial.println(kommaZahl_A + kommaZahl_B, 4);
  // * * * * * Assemble as String and then output *****
String output String = String (comma number_a, 2) + " + " + String (comma number_b, 2) + " = " + String(kommaZahl_A + kommaZahl_B, 4);
Serial.println(output string);
  // * * * * * assemble with sprintf and then output *****
dtostrf(kommaZahl_A, 5, 2, kommaZahl_A_str);
dtostrf(kommaZahl_B, 5, 2, kommaZahl_B_str);
dtostrf(kommaZahl_A + kommaZahl_B, 8, 4result buffer);
sprintf(output buffer, "%s + %s = %s", kommaZahl_A_str, kommaZahl_B_str, result, buffer);
Serial.println(output buffer);
void loop() {}


12.35 + 98.77 = 111.1111
12.35 + 98.77 = 111.1111
12.35 + 98.77 = 111.1111

Keyboard input is also possible via the serial Monitor. For this you use the query on Serial.available() and the function to read out the individual Bytes that have arrived via the serial connection. If you write the Byte into a char- variable, instead of numerical values, letters are output from the ASCII table:

char temp;
void setup() {
Serial.println("Wait for text input...");
void loop() {
  while(Serial.available()) {
temp =;


More Tips

Opening the serial monitor restarts the connected micro controller.

Variables should not be declared inside the setup()- Function. Preferably outside the functions as global variables. If they are declared in the loop()- Function, with each loop run new memory is reserved for the same variable, which can cause problems on micro controllers with little memory at some point.

Take a look at the English Arduino Reference for an extensive description of the functions that can be used in the Arduino IDE. Also test the examples. There is much to discover. In addition, there is a multi-part series with the theme Arduino IDE programming for beginners in the AZ Blog area. There you will find more tricks such as port manipulation to initialize and switch several digital pins at the same time.

We wish you a happy Advent season.

Andreas Wolter

for AZ-delivery Blog


Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. Install ESP32 now from the board manager
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP programming via WLAN