Notes Arduino Nano

Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

Notizen Arduino Nano

USB Driver
Arduino Nano needs a different USB driver for Windows 7

Driver chip is not FTDI but Winchiphead CH340

Download site: www.wch.cn/download/ch341ser_exe.html

➔ Com6

First Test
Arduino Blink Sketch

Tools → Board → COM6

Tools → Processor → Arduino Nano

Pinout Diagram
see https://forum.arduino.cc/index.php?topic=147582.0

Notizen Arduino Nano.docx 1/10


Symbolic Names for Arduino pins
see https://playground.arduino.cc/Main/CustomizeArduinoIDE

boards.txt
Path: Arduino/hardware/Arduino/avr/boards.txt

boards.txt describes the features of the available boards in the IDE, the size of the eeprom and the
the bootloader to be used.

For the Arduino Nano it says that the CPU is an ATmega328

boards.txt:


nano.menu.cpu.atrmega328=ATmega328

nano.build.core=Arduino
nano.build.variant=eightanaloginputs

The {ARDUINO}/hardware/arduino/variants directory tree contains 'pins_arduino.h' files that are


specific to a particular piece of hardware. The standard variant is, well, 'standard'. A typical variant
that you might use might be 'mega' (for the MEGA2560) or 'eightanaloginputs' (when your project
uses a surface mount ATmega328P rather than the through hole package, as the former has 2
additional analog inputs available).

For the Arduino Nano the chosen file is


{Arduino}/hardware/arduino/avr/variants/eightanaloginputs/pin_arduino.h

pin_arduino.h:

#include “../standards/pins_arduino.h”

{Arduino}/hardware/arduino/avr/variants/stanards/pin_arduino.h:

7-segment LED Display direct controlled


7-segment LED display SMA410362 common anode

Notizen Arduino Nano.docx 2/10


Sketch
#define ONES 10
#define TENS 11

byte characters[] = {
// 0,a,b,c,d,e,f,g
B01111110, // 0
B00110000, // 1
B01101101, // 2
B01111001, // 3
B00110011, // 4
B01011011, // 5
B01011111, // 6
B01110000, // 7
B01111111, // 8

Notizen Arduino Nano.docx 3/10


B01111011 // 9

};

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(PD2, OUTPUT);
pinMode(PD3, OUTPUT);
pinMode(PD4, OUTPUT);
pinMode(PD5, OUTPUT);
pinMode(PD6, OUTPUT);
pinMode(PD7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT); // decimal point
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
}

void loop() {
// put your main code here, to run repeatedly:

byte outbyte = characters[0];

for (int i=0; i<100; i++) {


Serial.println(i);
writeNumber(i);
}
}

void writeNumber(int number) {


int tens = number / 10;
int ones = number % 10;
for (int i=0; i<10000; i++) {
writeDigit(tens, TENS);
writeDigit(ones, ONES);
}
}

void writeDigit(int digit, int segment ) {


digitalWrite(ONES, LOW);
digitalWrite(TENS, LOW);

digitalWrite(PD2, !(characters[digit] & B01000000));


digitalWrite(PD3, !(characters[digit] & B00100000));
digitalWrite(PD4, !(characters[digit] & B00010000));
digitalWrite(PD5, !(characters[digit] & B00001000));
digitalWrite(PD6, !(characters[digit] & B00000100));
digitalWrite(PD7, !(characters[digit] & B00000010));
digitalWrite(8, !(characters[digit] & B00000001));

if (segment == ONES) {
digitalWrite(9, LOW);
digitalWrite(ONES, HIGH);
digitalWrite(TENS, LOW);
} else {
digitalWrite(9, HIGH);
digitalWrite(ONES, LOW);
digitalWrite(TENS, HIGH);

}
}

Sketch with Timer Interrupt – MsTimer2


Timer interrupt toggles the update of the two digits every 10ms

Manage Libraries → Add MsTimer2


/*
* 7-segment LED display with timer interrupt for refresh
*
* M. July 2017
*/

Notizen Arduino Nano.docx 4/10


#include <MsTimer2.h>

#define ONES 10
#define TENS 11

byte characters[] = {
// 0,a,b,c,d,e,f,g
B01111110, // 0
B00110000, // 1
B01101101, // 2
B01111001, // 3
B00110011, // 4
B01011011, // 5
B01011111, // 6
B01110000, // 7
B01111111, // 8
B01111011 // 9

};

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(PD2, OUTPUT);
pinMode(PD3, OUTPUT);
pinMode(PD4, OUTPUT);
pinMode(PD5, OUTPUT);
pinMode(PD6, OUTPUT);
pinMode(PD7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT); // decimal point
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);

MsTimer2::set(10, refreshDisplay); // refresh display every 10ms


MsTimer2::start();
}

void loop() {
// put your main code here, to run repeatedly:

byte outbyte = characters[0];

for (int i=0; i<100; i++) {


Serial.println(i);
writeNumber(i);
delay(1000);
}
}

unsigned int refreshcounter = 0;


int tens;
int ones;

void refreshDisplay(){
if (refreshcounter++ % 2 == 0) {
writeDigit(tens, TENS);
} else {
writeDigit(ones, ONES);
}
}

void writeNumber(int number) {


tens = number / 10;
ones = number % 10;
refreshDisplay();
}

void writeDigit(int digit, int segment ) {


digitalWrite(ONES, LOW);
digitalWrite(TENS, LOW);

digitalWrite(PD2, !(characters[digit] & B01000000));


digitalWrite(PD3, !(characters[digit] & B00100000));
digitalWrite(PD4, !(characters[digit] & B00010000));
digitalWrite(PD5, !(characters[digit] & B00001000));
digitalWrite(PD6, !(characters[digit] & B00000100));
digitalWrite(PD7, !(characters[digit] & B00000010));

Notizen Arduino Nano.docx 5/10


digitalWrite(8, !(characters[digit] & B00000001));

if (segment == ONES) {
digitalWrite(9, LOW);
digitalWrite(ONES, HIGH);
digitalWrite(TENS, LOW);
} else {
digitalWrite(9, HIGH);
digitalWrite(ONES, LOW);
digitalWrite(TENS, HIGH);

}
}

Setting the Counter with Rotary Encoder


see http://www.mathertel.de/Arduino/RotaryEncoderLibrary.aspx

Configure Digital-In Pins with Arduino integrated Pull-Up resistors.

The bouncing problem


When using contacts there is no exact ON and OFF condition while switching because the contacts
never close exactly and especially older contacts or dirty contacts generate a lot of fast ON/OFF
sequences (sometimes called noise).

Notizen Arduino Nano.docx 6/10


Hopefully when you stop turning the knob the contact situation should be fixed. If not, try to clean or
throw it away and buy a new one.

By using a capacitor it is possible to build a low pass filter that reduce the bouncing effect and
eliminates the very small spikes. If you ever have like to use this solution put the capacitor as near as
possible to the contacts. 100nF will do here.

Another solution is to detect changes of the signal in a very small timeframe and ignore them. You
can find a solution using this approach on the Arduino playground article.

The solution I found in some of the libraries around is to exactly follow all the 4 possible states of the
signals that a switch will pass when being turned from one position to the next and detect the next
position only when reaching a detent state. Even when a bouncing will occur it will not change the
position counting more than once.

Sketch

/*
* 7-segment LED display with rotary encoder
*
* M. July 2017
*/

#include <MsTimer2.h>

#define ONES 10
#define TENS 11

#define ROTARY_SWITCH 14
#define ROTARY_A 15
#define ROTARY_B 16

enum programMode {
count,
set_counter
};

byte characters[] = {
// 0,a,b,c,d,e,f,g
B01111110, // 0
B00110000, // 1
B01101101, // 2
B01111001, // 3
B00110011, // 4
B01011011, // 5
B01011111, // 6
B01110000, // 7
B01111111, // 8
B01111011 // 9

};

void refreshDisplay();

unsigned long currentTime;


unsigned long loopTime;

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(PD2, OUTPUT);
pinMode(PD3, OUTPUT);
pinMode(PD4, OUTPUT);
pinMode(PD5, OUTPUT);
pinMode(PD6, OUTPUT);
pinMode(PD7, OUTPUT);

Notizen Arduino Nano.docx 7/10


pinMode(8, OUTPUT);
pinMode(9, OUTPUT); // decimal point
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);

//rotary encoder
pinMode(ROTARY_SWITCH, INPUT_PULLUP); // switch
pinMode(ROTARY_A, INPUT_PULLUP); // Encoder A
pinMode(ROTARY_B, INPUT_PULLUP); // Encoder B

MsTimer2::set(10, refreshDisplay); // refresh display every 10ms


MsTimer2::start();

currentTime = millis();
loopTime = currentTime;
}

volatile programMode mode = count;


unsigned int refreshcounter = 0;
int number = 0;
int rotary_switch_old = HIGH;

void loop() {

byte outbyte = characters[0];

// get the current elapesed time


currentTime = millis();
if (mode == count) {
if (currentTime >= loopTime + 1000) {
// update counter every 1000 ms
number++;
Serial.println(number);
if (number > 99) number = 0;
loopTime = currentTime;
}
} else {
readRotaryEncoder();
}

void refreshDisplay(){
int tens = number / 10;
int ones = number % 10;

if (refreshcounter++ % 2 == 0) {
writeDigit(tens, TENS);
} else {
writeDigit(ones, ONES);
}
readSwitch();

if (mode == set_counter) {
readRotaryEncoder();
}

int rotary_a_old = HIGH;

void readRotaryEncoder() {

int rotary_a = digitalRead(ROTARY_A);


int rotary_b = digitalRead(ROTARY_B);

if (rotary_a == LOW && rotary_a_old == HIGH) {


if (rotary_b == HIGH) {
Serial.println("up");
number++;
if (number > 99) number = 0;
} else {
Serial.println("down");
number--;
if (number < 0) number = 99;
}
}
rotary_a_old = rotary_a;

Notizen Arduino Nano.docx 8/10


}

void readSwitch() {

int rotary_switch = digitalRead(ROTARY_SWITCH);

// check if rotary switch is pressed


if (rotary_switch == LOW && rotary_switch_old == HIGH) {
// key pressed
Serial.println("pressed");
rotary_switch_old = rotary_switch;
toggleMode();
} else if (rotary_switch == HIGH && rotary_switch_old == LOW) {
// key released
Serial.println("released");
rotary_switch_old = rotary_switch;
}
}

void toggleMode() {
if (mode == count) {
mode = set_counter;
} else {
mode = count;
}
}

void writeDigit(int digit, int segment ) {


digitalWrite(ONES, LOW);
digitalWrite(TENS, LOW);

digitalWrite(PD2, !(characters[digit] & B01000000));


digitalWrite(PD3, !(characters[digit] & B00100000));
digitalWrite(PD4, !(characters[digit] & B00010000));
digitalWrite(PD5, !(characters[digit] & B00001000));
digitalWrite(PD6, !(characters[digit] & B00000100));
digitalWrite(PD7, !(characters[digit] & B00000010));
digitalWrite(8, !(characters[digit] & B00000001));

if (segment == ONES) {
digitalWrite(9, LOW);
digitalWrite(ONES, HIGH);
digitalWrite(TENS, LOW);
} else {
digitalWrite(9, HIGH);
digitalWrite(ONES, LOW);
digitalWrite(TENS, HIGH);

}
}

7-segment LED Display with Shift Register


8-bit Shiftregister 74HC595

Notizen Arduino Nano.docx 9/10


Notizen Arduino Nano.docx 10/10

You might also like