Tinylab Book
Tinylab Book
1. Introduction 1
Library 12
For Windows 13
For Mac OS 14
We see production as the only way out to solve our country's problems.
But even more importantly, we believe we cannot afford the luxury of
leaving the problems of our world, to generations lacking problemsolving
abilities, ideas, art, technology, and solutions. As the Robotistan team, we
will continue to work with all our might to raise generations in our country
who love to produce.
#Don’tBeAfraidToProduce
Robotistan
Who Is This Book For?
This book appeals to a wide range of audiences, including students,
engineers, teachers, and individuals of all ages and levels of
knowledge/skill who are interested in learning Arduino programming.
Today, various starter kits are being prepared for those who want to learn
Arduino. These sets offer the essential components needed for individuals
to step into the world of microcontroller programming as a ready-to-use
package. Learning Arduino programming and engaging in various
projects in this field requires some skills in electronic circuit assembly.
While this may be a straightforward step for some individuals, at times,
setting up the circuit can prolong the learning process by involving
inevitable trial-and-error and troubleshooting difficulties, which can make
the process less enjoyable.
Not only beginners but also experienced individuals can benefit from the
practical usage of TinyLab. By encompassing commonly used
components in microcontroller projects, it accelerates your prototyping
process significantly.
In order to appeal to not only TinyLab users but also anyone interested in
learning Arduino, each lesson and project in the book includes a list of
materials and schematics for circuits that you can build yourself.
The lessons section of the book is designed to easily teach the usage of
each component found on TinyLab through easily understandable
examples, making it suitable for those with little experience or
knowledge. Starting from the most basic microcontroller applications
and progressing towards more complex ones, each application revisits
the topics covered in the previous lessons to build a strong foundation.
As a result, you will be able to easily tackle the projects in the second
part of the book. After completing the book, the only obstacle in creating
your own projects will be the limits of your imagination.
What Is Maker?
A maker is someone who, in the simplest definition, creates and produces
things. The culture known as DIY (Do it yourself) also falls under the
maker umbrella. Within this scope, individuals who work on projects
using Arduino and similar electronic hardware, design and print things
with 3D printers, build their own drones, and even those who enjoy
cooking and derive pleasure from it fit the maker definition.
Clone Boards
Since the Arduino platform is entirely open-source (both in terms of
hardware and software), all circuit diagrams, program codes, and PCB
layouts are readily accessible. Consequently, you can produce your own
Arduino board. The easy accessibility of these resources has also enabled
different manufacturers, particularly in countries with low production
costs like China, to produce Arduino boards. These types of boards are
commonly referred to as "clones" in the market and typically come with
more affordable price tags. While most clone boards offer the same
functionality as the original, the only potential issue could be the
manufacturing quality.
Tinylab
All Arduino boards, as mentioned, offer more than just the basic
functionality of blinking an LED on their own. You will need additional
components such as circuit elements, motors, sensors, communication
modules, etc., to fully utilize your Arduino board.
Arduino starter kits are available for this purpose, typically containing the
necessary materials and a breadboard for assembling circuits using these
materials. Additionally, if you plan to use your Arduino for more project-
focused purposes, there are "shields" available that come with pre-built
circuits ready to be attached onto the Arduino board. During the learning
process, circuits are often assembled on a breadboard, connections are
made with the Arduino, and quite frequently, the circuit doesn't work on
the first attempt due to a connection error. This is a natural part of the
learning process and is something that happens to everyone.
Tinylab not only benefits beginners but also provides great convenience
for those who have been using Arduino for a long time as a practical and
portable prototyping platform. You'll find it very useful for testing your
projects, especially IoT applications, as it neatly houses all the necessary
components in one place.
9
After clicking on the "Downloads" tab, you will see a screen where you
can download the file according to your operating system. At the time of
writing this book, the latest version of the Arduino software was 1.6.9.
For Windows users, you can click on the "Windows Installer" option.
Then, a page requesting donations will open. Depending on your
preference, you can choose to make a donation or simply click on the
"Just Download" option to download the software without donating.
10
After that, the software installation file starts to download. Once the
download process is complete, we open the file and initiate the
installation process. During the installation, we ensure that the "Install
USB driver" option is selected if prompted.
Now we can open our Arduino program. After opening the program, the
first thing we need to do is to configure the program to work with
Tinylab. We click on the Tools > Board menu and select Arduino
Leonardo.
Next, we select the port where our Arduino is connected from the Tools
menu > Port submenu. Note that the port number may vary on each
computer.
Now we have an Arduino program ready for use. In the program, the
functions written in the void setup() section run only once when the
board receives power. We set the input/output pins to be used, serial port
configuration, and other settings in this section. The void loop() section
contains the functions that will run continuously until the board loses
power after the commands in the setup function have been executed.
11
Arduino board is connected to our computer via USB, we can click on
the "Upload" option to upload our code to the board.
Libraries:
Arduino's own features and external hardware components, modules,
shield boards, etc., have ready-made codes called "libraries". Libraries
take over most of the heavy lifting from our code, such as communication
protocols, pin definitions, function definitions, etc., required for our
external hardware to work. We can easily use that external hardware by
simply including the relevant library in our code (for example, an LCD
screen).
For using components such as the LCD screen, real-time clock (RTC), 7-
segment display controller, external EEPROM, etc., found on Tinylab,
we need separate library files. The necessary libraries for the applications
included in the book are provided at the following link:
http://maker.robotistan.com/download/tinylab_libraries.zip
12
For Windows:
13
For Mac OS:
14
For GNU/Linux (Ubuntu MATE 16.04 LTS is
used):
15
If we have successfully completed the setup stage, we can now begin our
lessons.
Our first lesson will be the simplest example, which is to turn on and off
an LED.
• Breadboard
• Arduino
• 1 x LED
• 1 x 220Ω Resistor
• Jumper Cables
What is LED?
LED stands for Light Emitting Diode, which means a light-emitting
diode. Unlike the small bulbs we are familiar with and use in most of our
projects, LEDs have two different legs called anode and cathode. The
anode should be connected to positive voltage, represented by the +
symbol, while the cathode should be connected to negative voltage,
represented by the - symbol or ground (GND).
If we were to connect our LED directly to Arduino, the LED would have
the maximum amount of current provided by the board flowing through
it, potentially damaging either our LED or our board. To prevent this, we
need to connect a resistor in series with our LED to reduce the current.
Now, how do we determine the value of this resistor? This is where Ohm's
Law comes into play: V = i x R
5V = 0,020A x R
If we solve for R in this equation, we get the result of 250. This means
that we need a resistor with a value of 250 Ω (ohms) to use our LED with
a 5V voltage. It's not crucial to get the exact value; we can use the 220 Ω
resistor that we have available. That's enough theoretical information for
now. Now let's prepare our Arduino program. There are 4 LEDs
connected to digital output pins 10, 11, 12, and 13 on our Tinylab board.
We don't need any external connections or resistors to use these LEDs.
Additionally, most Arduino boards have an LED connected to pin 13 with
a series resistor next to it. This LED is typically marked with the letter
"L" on the board. Let's open our Arduino IDE program and follow these
steps to open the "Blink" example program:
18
Let’s review this code togerther:
pinMode(13, OUTPUT);
This line sets pin 13 on the board as an output. If we don't specify whether
the pin will be used as an input or output, any input or output functions
we write later in the program won't be able to use that pin.
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
This part first sets pin 13 to the HIGH logic level, which is 5V, waits for
1000 milliseconds (1 second) without performing any operations, and
then sets pin 13 to the LOW logic level, which is 0V or ground level.
After completing this process, the microcontroller waits again for 1
second without performing any operations using the delay function.
19
By changing the durations of the delay commands in this code, we can
alter the amount of time the LED remains on and off. If we want to use a
different pin, all we need to do is replace the pin number in the pinMode
and digitalWrite functions with the desired pin number. In the Tinylab
board, we can use LEDs connected to pins 12, 11, and 10 in addition to
pin 13. If we are making an external connection, we should remember to
include a 220 Ω resistor in series when connecting the LED to the
Arduino pin.
Arduino UNO ile devre şeması
• Arduino
• Breadboard
20
• 1 x Common Anode or Common Cathode RGB LED
• 3 x 220Ω Resistor
• Jumper Cable
If you are going to use Tinylab for the lesson, an RGB LED, 3 pieces of
220Ω resistors, and jumper cables will be sufficient. You can build the
circuit on the breadboard located on the board.
RGB LEDs, unlike regular LEDs, contain 3 different colored LEDs (red,
green, and blue) in a single package. As you may recall from our
previous lesson, LEDs have anode and cathode terminals. In RGB LEDs,
the anode or cathode connections are common, depending on the
manufacturing method of the LED.
Our RGB LED in the kit we're using has a common anode. Therefore,
the code we will prepare for Arduino will work according to the
common anode configuration. If we want to use a common cathode
LED, we will need to make a slight modification to our code.
as being lower.
%5, %50 ve %90 duty cycle değerlerine sahip PWM sinyalleri As seen
in the image above, if we provide 5V but only during 2 milliseconds,
which is just 5% of the total time, the resulting value will be 5% of 5V,
which is 0.25V. Similarly, if we set it to be open for half of the 2ms period
(50%), we get 2.5V. The percentage of time the signal is open within one
period is called the duty cycle.
Not all pins of our Tinylab board have PWM output capability. Some pins
on our board have a ~ sign in front of the pin number. We must use these
pins if we want PWM output. For Tinylab, which is Arduino Leonardo,
these pins are 3, 5, 6, 9, 10, 11, and 13.
22
Arduino UNO kartındaki PWM çıkış sunabilen dijital pinler
Since our Tinylab board does not have a built-in RGB LED, we make
our connections on the mini breadboard according to the following
diagram:
In our first lesson, we modified the existing sample code within the
Arduino software. This time, we are writing our own code:
//pin tanimlamalari
#define kirmiziPin 3
#define yesilPin 5 #define
maviPin 6
23
void setup() { //pinleri
cikis olarak ayarla pinMode(kirmiziPin,
OUTPUT); pinMode(yesilPin, OUTPUT);
pinMode(maviPin, OUTPUT); }
We connect the red leg of our RGB LED to pin 3, the green leg to pin 5,
and the blue leg to pin 6, each with a 220 Ω resistor. Since the LED is of
common anode type, we also connect the anode leg to the 5V pin of our
board.
In the setup function of our code, we define the pins we will use as outputs.
Additionally, the analogWrite command in the setColor function allows
us to adjust the voltage level we will receive from each PWM output pin.
24
The analogWrite command is used as follows: analogWrite(PWM çıkış
pin numarası, 0-255 arası sayısal değer);
In the loop function, our board repeatedly calls the setColor function we
created, allowing us to write the desired values to the outputs. As we
know, the delay function causes our board to wait without performing any
action between commands. By changing the value of this function, we can
25
achieve transitions between colors at the desired speed. You can also
experiment with different brightness values to obtain various colors.
26
Connection Diagram:
The code:
//LED pinleri
27
#define led1 13
#define led2 12 #define
led3 11 #define led4
10
digitalWrite(led1, HIGH);
digitalWrite(led2, LOW); digitalWrite(led3,
LOW); digitalWrite(led4, LOW);
Serial.println(“1 numarali LED yandi”);
break; case ‘2’:
digitalWrite(led1, LOW);
digitalWrite(led2, HIGH);
digitalWrite(led3, LOW); digitalWrite(led4,
LOW);
Serial.println(“2 numarali LED yandi”);
break; case ‘3’:
digitalWrite(led1, LOW);
digitalWrite(led2, LOW); digitalWrite(led3,
HIGH); digitalWrite(led4, LOW);
28
Serial.println(“3 numarali LED yandi”);
break; case ‘4’:
digitalWrite(led1, LOW);
digitalWrite(led2, LOW); digitalWrite(led3,
LOW); digitalWrite(led4, HIGH);
Serial.println(“4 numarali LED yandi”);
break; case ‘x’:
digitalWrite(led1, LOW);
digitalWrite(led2, LOW); digitalWrite(led3,
LOW); digitalWrite(led4, LOW);
Serial.println(“Tum LED’ler sondu”); break;
default: //hatali karakter girisinde uyari yap
Serial.println(“Yanlis giris yapildi.”);
break; }
}
}
In the beginning part of our code, we set pins 10, 11, 12, and 13 on the
Tinylab as outputs. This allows us to use the 4 LEDs located on the
board. The line Serial.begin(9600) in the setup section sets the serial port
of our Arduino to operate at 9600 baud (bits/s). The line while (! Serial)
prevents the code from proceeding until the serial port communication of
our board starts. Thus, when we open the serial port screen via the
Arduino IDE, we are greeted with the message "Enter an LED number
between 1 and 4 or turn off all with x".
To write any data to the serial port via Arduino, we use the Serial.print or
Serial.println functions. Serial.println, unlike the Serial.print command,
ensures that a line break is made after the sent text.
To read the data sent to the serial port by the computer, we use the
Serial.read function. In this example, we are only reading a single
character of data because the number of the LED we want to light up is
only one character long. Similarly, the letter "x" we use to turn off all
LEDs also occupies only one character. If we enter multiple characters in
the serial port screen, for example, typing 123, our Arduino will only
29
detect the last character written (in the example 123, since the last
character is 3, we will only see LED number 3 lit up).
Arduino board has both digital and analog pins. Until now, we have used
digital pins only for output functions. However, digital pins can also be
used with input devices such as sensors and buttons. In this lesson, we
will learn how to turn an LED on and off using two push buttons.
Tinylab has 4 buttons onboard. Buttons S1 and S2 are connected to
digital pins 9 and 8, respectively. If you are making external
connections, you can follow the diagram below for the wiring:
ledPin 12 #define
buttonApin 9 #define
buttonBpin 8
31
void loop() { //A butonuna
basilinca LED i yak if
(digitalRead(buttonApin) == LOW) {
digitalWrite(ledPin, HIGH); } //B butonuna
basilinca LED i sondur if
(digitalRead(buttonBpin) == LOW) {
digitalWrite(ledPin, LOW); }
}
If you noticed, when defining the pins where the buttons are connected,
we used a declaration like INPUT_PULLUP instead of just INPUT. By
doing this, we activate the pull-up resistor integrated into the digital pins
of the Arduino board. But what does the pull-up resistor do?
The pull-up resistor ensures that the signal remains intact when we use
digital pins as inputs. In this project, when the button is not pressed, the
value read from the digital pin is 5V, which corresponds to the logic
HIGH level. The pull-up resistor ensures that the voltage at this pin
remains at 5V as long as the button is not pressed and the value is not
pulled LOW. In this lesson, when we press button S1 on our Tinylab, the
32
L2 LED will turn on and stay on, and when we press S2, this LED will
turn off.
Although it's possible to use voltage levels lower than 5V with the
analog-to-digital converter in the microcontroller, we won't need this
capability since all analog inputs on the Tinylab board (potentiometer,
light sensor, and temperature sensor) operate at a 5V level.
Potentiometer
The potentiometer is actually a component found in almost all devices
we use daily. For example, the knob we turn to adjust the volume of our
music system is typically connected to a potentiometer. In simple terms,
a potentiometer is a resistor that we adjust by turning it with our hands.
In microcontroller applications, it is commonly used as a voltage divider.
When we turn the potentiometer in one direction, the resistance value
between its two terminals changes. We can observe this by measuring it
with a multimeter.
The potentiometer on our Tinylab board is connected to the A0 analog
34
input.
Temperature Sensor
The LM35 temperature sensor is an analog output temperature sensor that
provides precise temperature measurements. It has a sensitivity of 0.5°C
at 25°C. This sensor can be connected to Arduino's analog input to
perform temperature measurement applications.
If you don't have a Tinylab, you can set up your circuit according to the
circuit diagram below:
The code:
36
1024.0))) - 500) / 10.0; //lm35 i oku ve degeri santigrada
cevir
int lm35_val = (5.0 * analogRead(lm35_pin) * 100.0) / 1024;
Serial.print(“Potansiyometre degeri: “);
Serial.println(pot_val);
Serial.print(“LDR degeri: “);
Serial.println(ldr_val);
Serial.print(“Sicaklik degeri: “);
Serial.println(lm35_val); delay(100);
}
The output we receive from pin 2 of our LM35 temperature sensor
corresponds to a voltage drop of 10mV per 1°C. We need to scale the 5V
analog input range according to this ratio. We accomplish this with the
following line of code in our program:
int lm35_val = (5.0 * analogRead(lm35_pin) * 100.0) / 1024;
Similarly, to convert the voltage from the LDR into a meaningful lux
value representing the amount of ambient light, we use the following line
of code: int ldr_val = ((2500.0 / (analogRead(ldr_pin) * (5.0 /
1024.0))) - 500) / 10.0; For the data coming from the potentiometer, we
directly measure it as a value between 0 and 1023.
38
The connection of the RGB
LED is the same as the
schema we used in Lesson 2.
39
Tinylab üzerindeki S3 ve S4 butonlarının bağlantı şeması.
//LED baglantilari
#define kirmiziLEDPin 3
#define yesilLEDPin 5
#define maviLEDPin 6
//buton baglantilari
#define kirmiziSwitchPin 9
#define yesilSwitchPin 8
#define maviSwitchPin A5
//varsayilan degerler int
kirmizi = 0; int mavi =
0; int yesil =
40
0;
kirmizi = 0; }
} //yesil butonuna basildigi surece degeri birer arttir
if (digitalRead(yesilSwitchPin) == LOW) { yesil ++;
if (yesil > 255) { yesil = 0; }
} //mavi butonuna basildigi surece degeri birer arttir if
(analogRead(maviSwitchPin) >= 185 &&
analogRead(maviSwitchPin) <= 225) { mavi ++; if
42
analogWrite(yesilLEDPin, yesil);
analogWrite(maviLEDPin, mavi); }
If we recall our RGB LED code, we can see that we reused the setColor
function in this application. In our project, there is a push button for each
color that increases the brightness of that color. As long as these buttons
are pressed, the brightness value of the corresponding color increases,
and when it reaches 255, it resets back to 0.
S1 ile kırmızı, S2 ile yeşil, S3 ile mavi renklerin parlaklıklarını arttırabilir; S4 ile
LED’in tamamen sönmesini sağlayabilirsiniz.
If the LED you are using has a common cathode structure, you can apply
the same changes here as we did in our initial RGB project.
43
We can think of the component called a buzzer as a
small speaker. Although they do not produce
sound as loud and detailed as speakers, they are
sufficient for generating "beep" sounds.
In this project, we will create a code that plays the do, re, mi, fa, sol, la,
and si notes that we remember from elementary school music class. You
may recall that notes have two different representations: letter and name.
C = do, D = re, E = mi, F = fa, G = sol, A = la, and B = si. Since words
like "do" are used by different commands in programming languages, we
will use the letter representation of the notes in this code.
Here is our circuit diagram that you can use with Arduino:
The code:
44
#define buzzerPin A1 int
notaSayisi = 8;
//do, re, mi, fa, sol, la, si ve ince do icin frekans degerleri
int C = 262; int D = 294; int E = 330; int F = 349; int G =
392; int A = 440; int B = 494; int C_ = 523;
}
As you've noticed, our entire code is within the setup function. This
means that when we supply power to our Arduino board, the sound will
play only once and then stop. If we want the sound to play again, all we
need to do is press the reset button on the Arduino.
Tinylab üzerindeki buzzer, breadboard’un sağ üst köşesinde, reset butonu ile
USB bağlantısının hemen sağında yer alır.
45
To explain our code, we first input the frequency value for each note.
Then, we arranged these notes from the low C note to the high C note
into an array. We used a for loop to iterate through the contents of this
array and used the tone command for sound output. Once the tone
command is given, Arduino continues to output sound until it encounters
the noTone command.
46
If you're connecting a standard 16-pin LCD screen with your own
Arduino, you can set up your circuit according to the following wiring
diagram. For the connection of the LDR and temperature sensor, you can
refer to our analog input lesson.
If you want to check your screen connections, you can access the sample
code by following the steps File -> Examples -> LiquidCrystal ->
HelloWorld.
On Tinylab, to avoid restricting the input/output pins, an LCD screen is
used with the MCP23008 input/output expander integrated circuit that
operates with the I2C protocol. This allows all LCD functions to be fully
utilized with only 2 connection pins. The only thing we need to pay
attention to is including the library required for using this driver in the
code. Additionally, we should include the Wire.h library in our code,
which enables I2C communication with Arduino. The library required
for the LCD driver is included in the package mentioned in the
installation instructions in the early parts of our book. We can access the
sample applications that come with the library under File -> Examples ->
LiquidTWI2 (for example, HelloWorld).
In our application, we will print the sensor measurement data, which we
will recall from our analog input application, on our LCD.
47
The code for Tinylab:
//sensor pinleri
#define lm35_pin A3
#define ldr_pin A2
48
lcd.print(“\337C”); //imleci ikinci satir altinci karaktere
getir lcd.setCursor(5, 1); lcd.print(“Isik:”); //isik
degeri lcd.print(ldr_val); lcd.print(“ “); delay(250); }
//sensor pinleri
#define lm35_pin A3
#define ldr_pin A2
The parts located in the setup section of the code are making the
necessary configurations for our LCD driver library. Additionally, the
backlight of our LCD can also be turned on and off through a command
(lcd.setBacklight).
49
Lesson 09: 7 Segment LED Display
Materials needed for those who do not have Tinylab
• Arduino
• Breadboard
• 8 x 220Ω resistor
• 1 x 7 segment display
• Jumper cable
A 7-segment display is a type of numerical display commonly found in
elevator floor indicators, digital clocks, kitchen appliances, and
numerous other applications. It can display numeric characters as well as
some alphanumeric characters. The operating principle is quite simple:
to form a digit, the display consists of 7 (sometimes 8, including the
decimal point) LEDs. By lighting up specific LEDs, we can create the
desired digit. Similar to RGB LEDs, there are two types: common anode
and common cathode. Below, you can see the arrangement of a
7segment display in a common cathode configuration.
50
However, as you can see, it occupies quite a lot of pins. Assuming we
have 13 digital outputs on our Arduino board, it seems impossible to
directly connect even 2 digits. But there's a very simple solution to this:
using driver ICs. To drive the 4-digit 7-segment display found in
Tinylab, the MAX7219 integrated circuit is used. This allows all 4 digits
of the display to be controlled using just 3 digital pins.
The number 1 at the end of the configuration indicates that we will control
only 1 7-segment display. After ensuring that the switches located just
below the 7-segment display on our Tinylab are in the up position, we can
upload our code.
The code:
52
islemden once gostergeyi temizle lc.clearDisplay(0);
//gostergeye sicaklik degerini yaz if (temp <= 10) //sicaklik
tek basamakli ise { temp_first_digit = temp; //birler
basamagina sicakligi temp_second_digit = 0; //onlar
basamagina 0 yaz } //birler basamagini hesapla
temp_first_digit = temp / 10; //onlar basamagini hesapla
temp_second_digit = temp % 10; //birler basamagini gostergeye
yaz lc.setDigit(0, 0, temp_first_digit, false);
//onlar basamagini gostergeye yaz
lc.setDigit(0, 1, temp_second_digit,
false); //gostergeye santigrad derece sembolunu
yaz lc.setRow(0, 2, B01100011); lc.setRow(0,
3, B01001110); delay(1000); }
In our setup function, we give the command lc.shutdown(0, false) for the
operation of our display, and then we set the screen brightness with the
command lc.setIntensity(0, 8). The lc.clearDisplay(0) command is used
to clear any residual text on the display.
You may recall the temperature calculation formula from our analog
inputs lesson in the loop function. The next part focuses on displaying
the desired numbers or letters on the 7-segment display.
When introducing the 7-segment display, I mentioned that it has a total
of 8 LEDs. So how can we control these LEDs? The answer is simple: 1
byte of data corresponds to 8 bits. In the data of 1 byte size for each
digit, we can set the desired segments of that digit as on or off. For this,
we use the table below:
53
Using this table, we can create the letter "t" very conveniently as follows:
B00001111. Similarly, for the letter "I" we use B00000110, for the letter
"n" we use B01110110, and finally for the letter "y" we use B00111011.
In the lc.setRow(a, b, Bxxxxxxxx) function, the "a" part indicates which
7-segment display we will use, with 0 representing the first one, and the
"b" part indicates which digit we will use. Digit 0 represents the leftmost
digit, while digit 3 represents the rightmost one.
With the method described above, we can control each LED of each digit
individually. However, there is a much easier method for entering
numbers: the lc.setDigit(a, b, number, false) function. The usage of this
function is very similar to lc.setRow. Similarly, it is used to determine
which display and digit will be used for the first two parameters. Then,
the number that follows is used to write a digit between 0 and 9 to that
digit. Of course, another problem arises here: How do we write each
digit of a number one by one?
Fortunately, the solution to this is quite easy as well. For the units digit
of the number, we take its remainder when divided by 10 (mod 10), for
the tens digit, we take its division by 10, for the hundreds digit, we
divide it by 100, and for the thousands digit, we divide it by 1000. In our
application, we write the temperature value to the first two digits of our
7-segment display, and then we sequentially write the degree sign and
the capital letter C to the 3rd and 4th digits.
54
The small "if" statement in the code ensures that when the temperature
value is less than 10, it is written to the units digit, as numbers are
written from left to right.
55
Simply put, by measuring the signals coming from the A and B pins, we
can determine the direction of rotation and the number of revolutions of
the encoder based on which signal is leading.
The code:
//baslangic degerleri
int encoderPos = 0; bool
56
pinALast = LOW; bool n =
LOW;
57
On Tinylab, the A pin of the encoder is connected to digital pin 6, and
the B pin is connected to pin 7. Therefore, we define the connections at
the beginning of the code. We define a variable named encoderPos to
store the current position of our encoder, a variable named pinALast to
hold the previous position of pin A, and finally, a variable named n to
hold the current state of pin A.
In the loop function, first, we read the A pin using the digitalRead
function. We keep this value in the n variable and compare it with the
previous state of pin A. If the previous value of pin A was LOW and its
current value is HIGH, it indicates that the encoder has turned. To
determine in which direction the encoder has turned, we need to know
the order in which the A and B inputs become HIGH. Therefore, if the B
pin is LOW, we increment the encoder position value, and if it is HIGH,
we decrement it.
After this process, we write the encoder position value to the serial port
screen so that we can see the position of the encoder. To reset the
encoder position value, we will use the button on the encoder. If you
recall our button-controlled RGB LED lesson, the encoder button was
connected to pin A5 with a resistor. The value from pin A5 should be
between 80 and 100 (it may vary on each board, you can load the
AnalogReadSerial example first and read the value from pin A5 when
the encoder button is pressed).
59
This allows us to control devices that draw large currents using very
small currents.
Connection Diagram:
One of the pins of the motor output on our Tinylab board is connected to
the GND line via an NPN-type transistor. The other pin of the motor
output is connected to the +5V line. The base of the NPN transistor is
connected to digital pin 5. By providing a PWM signal to this pin, we
can change the current passing through the transistor and easily control
the speed of the motor.
60
Since the motor output is connected to the +5V line, the current from our
computer's USB port may be insufficient. Therefore, when using devices
that draw high currents like motors, let's make sure to power our Tinylab
with an external adapter or battery.
We upload the code to our Tinylab, disconnect the connection, connect
the motor to our board, and power our board with an adapter. You can
choose not to connect the USB cable to your computer if you wish.
I'd like to talk about the connections labeled NO, NC, and COM on the
relay outputs. The terminal labeled COM is the common connection
terminal. We connect the connection we want to switch to the COM
terminal of our relay, and if we want it to remain closed (open circuit)
when there is no power to the relay in our circuit, we make the external
circuit connection through the NO (normally open) terminal. If we want
the circuit to operate (short circuit) when there is no power to the relay,
we should use the NC (normally closed) terminal instead of NO. The
code we will upload is quite simple. We will make the relay energize
with the S1 button (D9) on the Tinylab and de-energize it with the S2
button (D8):
62
#define relayPin A4 #define
buttonApin 9 #define
buttonBpin 8
digitalWrite(relayPin, LOW); }
}
63
Lesson 12: Real Time Clock (RTC)
Materials needed for those who do not have Tinylab
• Arduino
• Breadboard
• 1 adet DS1307 RTC entegre
• 1 adet 0.1µF capacitor
• 2 x 10kΩ resistor
• 1 x 32.768kHz crystall
• 1 x CR2023 battery holder
• 1 x CR2023 battery
64
Tinylab.
DS1307 entegresinin bağlantı pinleri.
Our next step after placing the battery is to synchronize the RTC's clock
with our computer's clock. We will perform this process only once during
the initial setup. Once the clock is set correctly, it will continue to operate
until the battery runs out.
For those who will build their own circuit with Arduino instead of
Tinylab, here is our circuit diagram:
We upload the code found under File -> Examples -> DS1307RTC ->
SetTime to our Tinylab. After uploading the code, we open the serial port
65
monitor. If we see a statement like "DS1307 configured Time=16:25:43,
Date=Aug 12 2016," it means that the clock of our RTC integrated circuit
has been set.
The code:
setup() {
entegresinden tm formatinda
okunabiliyorsa {
//saat formati: SS:DD:ss
Serial.print(“Saat = “);
print2digits(tm.Hour);
Serial.write(‘:’);
print2digits(tm.Minute);
Serial.write(‘:’);
print2digits(tm.Second); //tarih
formati: GG/AA/YYYY Serial.print(“,
Tarih (G/A/Y) = “);
Serial.print(tm.Day);
Serial.write(‘/’);
Serial.print(tm.Month);
Serial.write(‘/’);
Serial.print(tmYearToCalendar(tm.Year));
Serial.println(); } else //hata mesajlari { if
66
(RTC.chipPresent()) //RTC okunuyor fakat saat ayarli degilse
{
Serial.println(“RTC saati ayarli degil.”);
Serial.println(“Lutfen once SetTime programi ile saati
ayarlayin.”); Serial.println(); } else //RTC
okunamiyorsa {
Serial.println(“RTC okuma hatasi.”);
Serial.println();
} delay(9000); }
delay(1000); }
68
We will examine the usage of EEPROM in two parts: writing and
reading data. As an example of writing, we will store the information
coming from the temperature sensor on the Tinylab into the EEPROM:
//gerekli kutuphaneler: 24LC256 icin ExtEEPROM.h, I2C
haberlesme icin Wire.h #include <ExtEEPROM.h>
#include <Wire.h> //24LC256 I2C adresi
ExtEEPROM eeprom(hwaddress);
void setup()
{
Serial.begin(9600); Serial.println(“EEPROM yazma
ornegi.”); delay(3000); //adres degeri 256 olana kadar
EEPROM’a sicaklik degerlerini yaz for (int addr = 0; addr <=
256; addr++) { //lm35 i oku ve degeri santigrada cevir
int val = (5.0 * analogRead(A3) * 100.0) / 1024; //degeri
EEPROM’un addr ile belirtilen byte’ina yaz
eeprom.write(addr, val); //suan okunan EEPROM adres
numarasini yaz
Serial.print(addr);
//bosluk birak
Serial.print(“\t”);
//EEPROM’a yazilan sicaklik degerini ekrana yaz
Serial.println(val); delay(200); }
Serial.print(“Hafiza sonuna gelindi.”);
}
void loop()
{
}
I mentioned that the EEPROM integrated on the Tinylab is located at
I2C address 0x50. The line #define hwadress 0x50 at the beginning of
69
the code defines the address for I2C communication, thus in this
example, we define the address as 0x50. This is a constant address used
for communication with the integrated circuit. When discussing what
EEPROM is, I mentioned that the 24LC256 has 256KB of memory. This
corresponds to a total of 262,144 addresses, each capable of storing data
of 1 byte in size (256KB = 256 x 1024 = 262,144 bytes). To write data to
each byte of memory, we need to address each memory location
individually. A simple for loop inside our loop() function starting from
address 0 up to 255 writes a temperature value to one of the EEPROM
memory locations every half second.
If you noticed, we are only using the first 256 bytes of the EEPROM.
There are 261,888 more addresses available (262,144 - 256) that we
could use.
Another point to note is that the data we write must be 1 byte in size. So,
if we want to write an integer numerical value, the largest value we can
write is 255. This is because a 1-byte data consists of 8 bits. Since 2^8
equals 256, we can only use the range from 0 to 255 for integer-type
variables.
To read the data written to the EEPROM, we use the following code:
//gerekli kutuphaneler: 24LC256 icin ExtEEPROM.h, I2C
//haberlesme icin Wire.h
#include <ExtEEPROM.h> #include
<Wire.h>
void setup()
{
//seri iletisimi 9600 baud’da baslat
Serial.begin(9600); Serial.println(“EEPROM okuma
ornegi.”); delay(3000); //adres degeri 256 olana
kadar EEPROM’dan veri oku for (int addr = 0; addr
70
<= 320; addr++) { //EEPROM’dan addr adresindeki
veriyi oku int val = eeprom.read(addr);
//suan okunan EEPROM adres numarasini yaz
Serial.print(addr);
//bosluk birak
Serial.print(“\t”);
//EEPROM’dan okunan veriyi ekrana yaz
Serial.println(val); delay(200); }
Serial.print(“Hafizanin sonuna gelindi”);
}
void loop()
{
As you can see, the code used for reading is very similar to the one used
for writing. The function eeprom.write() is replaced with eeprom.read()
for reading.
For those who will build their own circuit with Arduino, here is our
circuit diagram:
72
When making connections, it's important to note that if you are using a
board like Arduino Leonardo, the SPI connections are not brought out to
digital pins. Therefore, you need to use the ICSP (In-Circuit Serial
Programming) pins for the connection.
The code:
//gerekli kutuphaneler: SPI haberlesme icin SPI.h,
//SD kart icin SD.h,
//I2C haberlesme icin Wire.h,
//saat fonksiyonlari icin Time.h,
//DS1307 RTC entegresi icin DS1307RTC.h,
//I2C LCD icin LiquidTWI2.h
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <LiquidTWI2.h>
73
//SD kartin chip select (CS) pini ve sicaklik sensoru pin
tanimlamalari #define chipSelect 4 #define LM35_pin A3
75
In this tutorial, we'll also be using
the Time.h, DS1307RTC.h, and
LiquidTWI2.h libraries
because we'll be using
RTC (Real-Time Clock) and an
LCD display in addition to the SD
card. We included the Wire.h
library because both RTC and the
LCD screen use I2C (TWI)
communication. The CS (Chip
Select) pin of the SD card on
Tinylab is connected to digital pin
4, and the LM35 temperature
sensor is connected to pin A3. We
define these pins at the beginning
of our code.
In the setup function, we initialize
the LCD and SD functions. The
code here is designed to display error messages on the LCD in case of any
connection errors with the SD card or if there's no SD card in the Tinylab
slot. This allows us to easily identify any errors that may occur.
76
In the loop function, we perform temperature measurement as we did in
our analog value reading tutorial. However, in this case, since the data
format we'll write to the SD card is defined as a string, we convert the
temperature value to a string using the command dataString +=
String(temp);.
If we're able to read the time information from the RTC (Real-Time
Clock) module, we create a file named "datalog.txt" using the command
File dataFile = SD.open("datalog.txt", FILE_WRITE); and start writing
to this file.
The format of the data we'll store on the SD card will be as follows:
If you observe the code carefully, you'll notice that we're incorporating
the date and time using the same method we used in our previous RTC
tutorial. However, in this project, we're using the date and time in the file
we write to the SD card instead of displaying it on the serial monitor.
77
In this section, we will learn how to create various projects by using
multiple circuits on Tinylab together. These projects include the use of
HC-06 Bluetooth, XBee RF, nRF24L01 RF, and ESP8266 WiFi modules,
which are part of Tinylab's IoT Kit and Exclusive Kit. For some wireless
communication projects, we will need two Arduino boards, one acting as
a transmitter and the other as a receiver. Additionally, we will utilize
various additional modules, shields, and external components to use our
Arduino in various projects. You can obtain all of these products through
stores such as Robotistan.com.
The code:
79
lc.setIntensity(0, 8); //gostergeyi temizle
lc.clearDisplay(0); }
81
basamaga eksi isareti koy lc.setRow(0, 0, B00000001);
}
}
}
At the beginning of our code, we defined the pins for the motor driver and
potentiometers connected to the Tinylab. Then, we added the necessary
library to use the 7-segment display and defined the pins. We also defined
two variables, motor_spd for the motor speed and percent for the motor
speed percentage, and initialized them to zero. In the setup function, we
set the pin connected to the motor as an output and made the necessary
settings for our 7-segment display.
1023, being approximately 4 times 255 (since there are actually 256 steps
between 0 and 255, and 1024 steps between 0 and 1023), a simple division
operation is sufficient for us. However, if we want to map the range to
another range (for example, mapping the range from 0 to 255 to -100 to
+100), it is more convenient to use the map function. The usage of this
function is as follows:
istenilen_altlimit, istenilen_ustlimit)
82
In this application, since we want to view the motor speed as a
percentage, we used the map function in the following way:
map(motor_spd, 0, 255, 0, 100). The printToDisplay function at the
bottom of the code allows us to easily write values to the 7-segment
display in the rest of the code by using printToDisplay(numeric_value)
format. If you want to examine the functions here, you can refer to our
7segment display lesson.
83
The ESP8266 establishes a
connection with the Tinylab using
the UART communication
interface. Its usage is
straightforward. By connecting the
module to the ESP8266 socket on
the Tinylab as shown in the image
below, we can start using it
immediately.
This code serves as a bridge between the virtual serial port used by our
Tinylab for communication with the computer via USB and the hardware
port connected to the ESP8266 module. To confirm that our ESP8266
module is functioning correctly, we open the serial port monitor and
send the AT command. If you receive the "OK" response as seen in the
screenshot below, it means your module is working fine.
To list the WiFi access points in the coverage area, we issue the
command "AT+CWLAP".
85
To connect to a wireless access point listed here, we use the command:
AT+CWJAP=”kablosuz_ag_ismi”,”sifre”
disconnect from the wireless access point, we use the command: AT+CWQAP
In addition, here are some other commands:
86
AT+GMR -> Shows the firmware version.
For all AT commands of the ESP8266 module, you can refer to the PDF
file available on the GitHub link.
https://github.com/keremizgol/tinylab-
kitap/blob/master/kodlar/projeler/esp8266_bridge/4AESP8266__AT_Ins
truction_Set__EN_v0.30.pdf
Before starting our project, you need to follow the instructions in the
"Using the ESP8266 WiFi Module" project to pair your module with a
wireless access point and connect it to the internet. Once you've done
that, you can create a new account on ThingSpeak.com and begin this
project. It's important to enter the correct "Time Zone" setting to ensure
that the sensor data is recorded with the correct timestamp.
87
After creating our account, we need to create a new channel by clicking
the "New channel" button under the "Channels" tab. You can configure
the channel settings as shown in the screenshot below. You don't need to
write it exactly as shown, but make sure that "Field 1" option is enabled.
After configuring the channel settings, we will need the "Write API Key"
under the "API Keys" tab. We need to write this key into the line "String
api_key = "xxxxxxxxxxxxxxxx";" in our code.
88
After completing these steps, when we log into our ThingSpeak account
and click on "My Account" in the top right corner, we should be able to
see the channel we created.
If we have reached this point smoothly, now it's time to upload the code
to Tinylab.
//thingspeak.com ip adresi
#define IP “184.106.153.149”
//sicaklik sensoru pin baglantisi
#define lm35_pin A3
89
//Thingspeak’ten alacaginiz Write API Key
//kodu yuklemeden once degistirmeyi unutmayiniz
setup()
{
//USB-seri baglantisi
Serial.begin(9600);
//Tinylab-ESP8266 baglantisi
Serial1.begin(115200); delay(5000); }
Serial.println(String(“AT+CIPSTART=\”TCP\”,\””) + IP +
“\”,80”);
Serial1.println(String(“AT+CIPSTART=\”TCP\”,\””) + IP +
“\”,80”); delay(1000); if (Serial1.find(“Error”))
//baglanti hatasi durumunda seri monitorden bildir {
delay(1000);
91
92
7-segment ile rotary encoder
In this project, we will use the rotary encoder together with our 7segment
display, which we have used before.
//baslangic degerleri
int encoderPos = 0;
bool pinALast = LOW;
bool n = LOW; void
setup() {
93
//enkoder pinlerini giris olarak ayarla, pull-up direnclerini
aktiflestir pinMode (pinA, INPUT_PULLUP); pinMode (pinB,
INPUT_PULLUP); //gostergeyi calistir lc.shutdown(0, false);
//gosterge parlakligini 0-15 arasinda ayarla
lc.setIntensity(0, 8); //gostergeyi temizle
lc.clearDisplay(0); }
94
10), false);
//sayiyi 10’a bol, sonucun 10 ile bolumunden kalani onlar
basamagina yaz lc.setDigit(0, 2, ((value / 10) % 10),
false); //sayiyi 100’e bol, sonucun 10 ile bolumunden kalani
yuzler basamagina yaz lc.setDigit(0, 1, ((value / 100) %
10), false); //diger basamaklari bos birak lc.setRow(0,
0, B00000000); } //dort basamakli sayilar if (value
>= 1000) { //birler basamagina sayinin 10 ile bolumunden
kalani yaz lc.setDigit(0, 3, (value % 10), false);
//sayiyi 10’a bol, sonucun 10 ile bolumunden kalani onlar
basamagina yaz lc.setDigit(0, 2, ((value / 10) % 10),
false); //sayiyi 100’e bol, sonucun 10 ile bolumunden kalani
yuzler basamagina yaz lc.setDigit(0, 1, ((value / 100) %
10), false); //sayiyi 1000’e bol, sonucun 10 ile bolumunden
kalani binler basamagina yaz lc.setDigit(0, 0, ((value /
}
Our code is actually very simple. The setup function consists of a
combination of the 7-segment display lesson and the rotary encoder
lesson. The loop function is almost the same as the one in the rotary
encoder lesson, with the difference being that the encoder position is
displayed on the 7-segment display instead of the serial monitor. To
easily display values on the 7-segment display, we use the
printToDisplay() function. In this function, we first check if the
incoming parameter (the int value parameter inside the parentheses) is
negative or positive. If the incoming value is negative (i.e., if the encoder
is turned counterclockwise), a minus sign is added to the beginning of
the value. Remembering how each LED of the 7-segment display is
configured from the 7-segment display lesson, we know that we need to
enter the value B00000001 for the minus sign. Additionally, for the
value to be displayed properly, each digit of our 7-segment display needs
to be sent to the display individually. For this, we use the modulo
operator (%) and a simple division operation. For negative numbers, we
use the abs() function to obtain the absolute value of the number.
We can easily copy the printToDisplay function included in this project
to any other project we want, allowing us to easily write integer values to
the 7-segment display on the Tinylab. Additionally, we can control
variables such as motor speed and servo motor position with the rotary
encoder.
96
times, for example, to blink an LED. However, what if we want to do
multiple tasks at the same time?
In this case, we need to think a bit more carefully when writing code. We
will instruct Arduino to perform the required tasks at certain time
intervals while continuously monitoring the time. For example, instead
of sitting in front of the washing machine waiting for it to finish after
filling it up and starting it, we can periodically check whether the
washing is finished. Meanwhile, we can engage in other tasks. The
millis() function in Arduino allows us to obtain the running time of the
program in milliseconds. As long as there is no power outage, this
function resets to zero after counting for approximately 50 days. By
using this function, we can note the time of the tasks performed by our
program and check whether the millis() function has increased by the
repetition period to perform the same waiting operation. Let's try writing
the LED blinking, which is essential in Arduino programs, using this
method.
//LED’in bagli oldugu pin
#define ledPin 13
1000;
loop()
{
//suanki zamani hafizada tut unsigned
long simdikiZaman = millis();
97
//zaman bilgisini sifirla
oncekiZaman = simdikiZaman; //ledDurum’u
tersine cevir ledDurum = !ledDurum; }
The loop function may seem a bit complicated, but what we are doing is
quite simple: We store the current millis value, which is essentially the
Arduino's clock, in the variable simdikiZaman. If the time elapsed since
the last time the LED was turned on or off is equal to or greater than the
desired blinking interval (specified by the aralik variable), we enter the if
statement. Inside the if statement, we reset the time (set it equal to the
current time) and change the state of the LED. After this change, the
digitalWrite(ledPin, ledDurum); command outside the if statement
controls whether the LED turns on or off based on the value of the
ledDurum variable.
We can easily modify this to make two LEDs blink at different speeds
using the following code:
98
//baslangic degerleri ve bekleme sureleri
bool led1Durum = LOW; bool led2Durum =
LOW; unsigned long oncekiZaman1 = 0;
unsigned long oncekiZaman2 = 0; const long
aralik1 = 500; const long aralik2 =
300; void
setup()
digitalWrite(led2Pin, led2Durum);
}
99
Thermometer and Calender Clock
In this project, we will create a clock application using the RTC, LCD,
temperature sensor, and 7-segment display on the Tinylab.
Before uploading the code for the project, I recommend reviewing the
lessons related to the components used in the project. This project serves
as a good example of using multiple components together on the Tinylab
and avoiding the use of the delay function for waiting
102
basamak yaz lc.setDigit(0, 0, temp_first_digit, false);
lc.setDigit(0, 1, temp_second_digit, false); //7-segment
gostergenin son iki hanesine santigrad derece sembolu yaz
lc.setRow(0, 2, B01100011); //derece sembolu lc.setRow(0, 3,
B01001110); //C harfi
}
103
besinci sutuna getir lcd.setCursor(4, 1); if (tm.Hour <
10) //saat tek haneliyse basina 0 koy lcd.print(“0”);
//saat bilgisini yaz lcd.print(tm.Hour); //saat ile
dakika ayiraci koy lcd.print(“:”); if (tm.Minute < 10)
//dakika tek haneliyse basina 0 koy lcd.print(“0”);
//dakika bilgisini yaz lcd.print(tm.Minute); //dakika
ile saniye ayiraci koy lcd.print(“:”); if (tm.Second <
10) //saniye tek haneliyse basina 0 koy lcd.print(“0”);
//saniye bilgisini yaz lcd.print(tm.Second); } else
//RTC okunamiyorsa ekrana hata mesaji yaz { if
(RTC.chipPresent()) { lcd.setCursor(0, 0);
lcd.print(“RTC Okuma Hatasi”); }
}
#include <SPI.h>
#include <MFRC522.h>
#include <EEPROM.h>
10
key;
105
EEPROM.write(i + 4, readCard[i] );
}
Serial.println(“Kart EEPROM’a kaydedildi.”);
Serial.println();
Serial.println(“Kart kayit islemi basarili!”); } void
loop() { }
#define RST_PIN 9
106
#define SS_PIN 10
#define relayPin A4
kart2 = “”;
MFRC522::MIFARE_Key key;
void setup()
{
Serial.begin(9600);
SPI.begin();
mfrc522.PCD_Init(); pinMode(relayPin, OUTPUT);
Serial.println(“RFID KART OKUMA UYGULAMASI”);
Serial.println(“--------------------------”);
Serial.println(); readEEPROM(); }
void loop() { if ( !
mfrc522.PICC_IsNewCardPresent()) { return; }
if ( ! mfrc522.PICC_ReadCardSerial()) {
return; }
String rfid = “”; for (byte i = 0; i < mfrc522.uid.size;
i++) { rfid += mfrc522.uid.uidByte[i] < 0x10 ? “ 0” : “
Serial.print(“Kart 1: “);
Serial.println(kart1);
Serial.print(“Kart 2: “);
Serial.println(kart2);
Serial.print(“Okunan: “);
Serial.println(rfid);
107
Serial.println();
if (rfid == kart1)
{ digitalWrite(relayPin,
HIGH);
Serial.println(“Role kesimde.”); } if (rfid == kart2)
{ digitalWrite(relayPin, LOW);
Serial.println(“Role
iletimde.”);
} Serial.println();
delay(200); }
String(EEPROM.read(i), HEX); }
}
At this stage, when we read the card numbered 1, our relay will turn on,
and when we read the card numbered 2, it will turn off.
108
109
Controlling LED via Smart Device Using
HC-06 Bluetooth Module
Bluetooth, a technology present in almost all devices from our
smartphones to our headphones, provides wireless communication
capability. In order to add Bluetooth connectivity support to our projects
with Arduino, various modules are available on the market. Tinylab has
a compatible connection port for popular Bluetooth modules such as
HC05 and HC-06:
HC06 modül konektörü, Tinylab kartı üzerinde buzzer’ın hemen üst kısmında yer
alır.
110
In this project, we will use the HC-06 module. It is also possible to use
the HC-05 instead of HC-06, but the configuration procedure works
differently. In the first stage of our project, we will change the name of
our module, the baud rate setting, and the password it will ask for
connection. During configuration, there should be no connection to the
module via Bluetooth. When there is no connection, the LED on the
module will flash rapidly.
Name: linvor
Password: 1234
Baud rate: 9600
Serial.begin(9600);
111
Serial1.begin(9600); } void loop()
{
if
(Serial1.available()) { int
inByte = Serial1.read();
Serial.write(inByte);
} if (Serial.available())
{ int inByte =
Serial.read();
Serial1.write(inByte);
}
}
We open the serial monitor screen in the Arduino IDE and make sure
that the settings are as follows:
To test whether communication with the module has started, we can type
"AT". The module should respond with "OK". Then, we can use the
following commands to change its settings:
AT+NAMEkartismi
112
To change the password (PIN), use the command: AT+PIN1234
To change the baud rate, use the command: AT+BAUD4 (1:1200, 2:2400,
3:4800, 4:9600, 5:19200, 6:38400, 7:57600, 8:115200, A:460800,
B:921600, C:1382400).
114
digitalWrite(led1, LOW); digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW); Serial1.println(“Tum LED’ler
sondu”); break;
default: //hatali karakter girisinde uyari yap
Serial1.println(“Yanlis giris yapildi.”); break; }
}
}
As keen readers will notice, this code is almost identical to the one in our
3rd serial communication lesson. The only difference is that we use
Serial1 instead of Serial. This is because Tinylab's core, the Arduino
Leonardo, uses the virtual serial port Serial for communication via USB,
while it uses the physical serial port Serial1 for communication with
external components like XBee and Bluetooth modules.
115
After completing the pairing process, we launch the BlueTerm
application. Clicking on the "Connect device" option, we select the name
we gave to our HC06 module from the list (the name I preferred was
Tinylab_HC06).
116
Once the connection is established, our project is ready to run.
117
XBee Remote Sensor Module
XBee modules are commonly preferred wireless communication
solutions in Arduino projects. XBee is the name given to the wireless
communication devices produced by Digi. These modules use the IEEE
802.15.4 network protocol, providing point-to-point or multi-connection
capabilities. The main difference from Zigbee, which is often confused
with it, is that XBee is Digi's proprietary Zigbee protocol. There are
many XBee modules on the market with different features. The simplest
ones are the XBee 802.15.4 modules, also known as Series 1. When you
obtain these modules, you can easily establish wireless communication
between two devices without any configuration. In this project, we will
use two devices: Tinylab and the XBee Explorer board.
118
XBee modülü için bağlantı konektörü, Tinylab’imizde SD kart soketinin hemen
üzerindedir.
119
In this project, Tinylab will wirelessly send us the ambient temperature
and humidity values via XBee.
The code:
ldr_pin A2 #define
lm35_pin A3 void setup()
{
//seri iletisimi 9600 baud’da baslat
Serial1.begin(9600); //seri monitor acilana kadar bekle
while (! Serial1); Serial1.println(“XBee kablosuz
haberlesme ornegi.”); delay(3000); }
120
Serial1.print(“Sicaklik degeri: “);
Serial1.println(lm35_val); delay(500);
}
We will observe the communication over the serial port with the XBee
Explorer board and our XBee module connected to our computer. For
this, we can use a serial terminal program like PuTTY, or we can use the
serial port monitor of the Arduino IDE. All we need to do is select the
COM port where our XBee Explorer board is connected.
121
Thus, by measuring the acceleration due to gravity, we can obtain the
orientation of the object in three-dimensional space. The information
obtained from the accelerometer will be in units such as m/s^2 or
multiples of the force of gravity (g). A gyroscope, on the other hand, is
used to measure the motion of an object around any axis. In a stationary
position, a gyroscope will measure zero or a very small value. As the
object moves, the gyroscope sensor will provide us with the speed of this
movement in units like degrees per second.
To see the addresses of the I2C devices on our Tinylab, we can use the
following I2C scanner code:
// --------------------------------------
// i2c_scanner
//
// Version 1
// This program (or code that looks like it) // can
be found in many places.
// For example on the Arduino.cc forum.
// The original author is not know. //
Version 2, Juni 2012, Using Arduino 1.0.1
// Adapted to be as simple as possible by Arduino.cc user
Krodal
// Version 3, Feb 26 2013
122
// V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3 // by
Arduino.cc user Krodal.
// Changes by louarnold removed.
// Scanning addresses changed from 0...127 to 1...119,
// according to the i2c scanner by Nick Gammon
// http://www.gammon.com.au/forum/?id=10896 //
Version 5, March 28, 2013 // As version 4,
but address scans now to 127.
// A sensor seems to use address 120.
// Version 6, November 27, 2015.
// Added waiting for the Leonardo serial communication.
//
//
// This sketch tests the standard 7-bit addresses //
Devices with higher bit address might not be seen properly.
//
123
if (error == 0) { Serial.print(“I2C device
found at address 0x”); if (address < 16)
Serial.print(“0”);
Serial.print(address, HEX); Serial.println(“
!”);
nDevices++;
} else if (error == 4) {
Serial.print(“Unknow error at address 0x”); if
(address < 16) Serial.print(“0”);
Serial.println(address, HEX);
}
}
if (nDevices == 0) Serial.println(“No
I2C devices found\n”); else
Serial.println(“done\n”); delay(5000); //
After uploading this code, when we open the serial port screen, we
should encounter the following view:
124
The listed I2C devices here are as follows:
The sensor's X, Y, and Z axes are indicated on the module, and its
default I2C address is 0x68. Remember, this address is also used by the
125
DS1307 integrated circuit on our Tinylab. To avoid address conflicts like
this, we can use the AD0 pin on the module. When we provide 5V to this
pin, the address of our MPU6050 will change to 0x69. We connect our
sensor according to the diagram below and rerun our I2C scanner code:
When we run the code, we should see an additional I2C device with
address 0x69 on the serial port screen, like this:
If we see the device with address 0x69 in the list, it means our
connections are correct. Now, we can upload the code we will use with
our sensor:
//gerekli kutuphaneler: I2C icin Wire.h,
126
//I2C LCD icin LiquidTWI2.h
#include <Wire.h>
#include <LiquidTWI2.h>
//baslangic degerleri
int AcX = 0; int AcY
= 0; int AcZ = 0;
127
//ACCEL_XOUT_H registerini (0x3B adresinde) oku
Wire.write(0x3B);
//haberlesmeye devam et
Wire.endTransmission(false);
//toplam 6 adet register’dan bilgi oku
Wire.requestFrom(MPU_addr, 6, true); //her eksenin bilgisi
toplam 2 byte (16-bit) oldugundan iki ayri register’da
tutuluyor AcX = Wire.read() << 8 | Wire.read(); // 0x3B
(ACCEL_XOUT_H) ve 0x3C (ACCEL_XOUT_L) //16-bit veriyi -100
ile +100 arasinda olcekle
AcX = map(AcX, -32768, 32767, -100, 100); AcY =
Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) ve 0x3E
(ACCEL_YOUT_L) //16-bit veriyi -100 ile +100 arasinda olcekle
AcY = map(AcY, -32768, 32767, -100, 100); AcZ =
Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) ve 0x40
(ACCEL_ZOUT_L) //16-bit veriyi -100 ile +100 arasinda olcekle
AcZ = map(AcZ, -32768, 32767, -100, 100);
}
128
lcd.setCursor(3, 0); lcd.print(abs((AcX / 100) % 10));
lcd.setCursor(4, 0); lcd.print(abs((AcX / 10) % 10));
lcd.setCursor(5, 0); lcd.print(abs(AcX % 10)); }
10)); }
}
129
With this code, we display the sensor data we obtained from the
MPU6050 accelerometer on the LCD screen of Tinylab. Since the
sensor's output is 16-bit, the measured value for each axis will vary
between -32768 and +32767. For practical use, we scale these values to a
range of -100 to +100 using a simple map command.
130
one connected to the Arduino Uno with Joystick Shield will be set as
the transmitter.
The Arduino Joystick Shield we will use in the project comes with a
ready socket for the nRF24L01 wireless module. This makes it very
convenient to use.
131
We will create a gamepad by attaching the joystick shield to our Arduino
Uno. The connections for the Joystick Shield are as follows:
The code we will upload retrieves the values of these buttons and axes,
storing them in a variable of type String. Later, this String is sent via the
nRF transmitter.
133
dataString += String(digitalRead(button3)); dataString
+= “,”; //buton4 degerini gonderilecek
String’e ekle dataString +=
String(digitalRead(button4)); dataString += “,”;
//buton5 degerini gonderilecek String’e ekle
dataString += String(digitalRead(button5)); dataString
+= “,”; //buton6 degerini gonderilecek
String’e ekle dataString +=
String(digitalRead(button6)); dataString += “,”;
//buton7 degerini gonderilecek String’e ekle
dataString += String(digitalRead(button7)); dataString
+= “#”; //String’i gonder
transmitter.txPL(dataString); //gonderme metodu
hizli, karsi taraftan alindi mesajini bekleme
transmitter.send(FAST); //String’i bosalt dataString
= “”; delay(50); }
On the receiver side, the incoming String is split into its components, and
the joystick axes and buttons are moved accordingly based on these
values.
//Gerekli kutuphaneler: SPI haberlesme icin SPI.h,
//nRF24L01 modulu icin nRF24L01p.h,
//Bilgisayarin Tinylab’i joystick olarak taniyabilmesi icin
Joystick.h
#include <SPI.h> #include
<nRF24L01p.h>
#include <Joystick.h>
//varsayilan degerler
int pos_x = 0; int
134
pos_y = 0; int a_btn
= 0; int b_btn = 0;
int c_btn = 0; int
d_btn = 0; int e_btn
= 0; int
f_btn = 0; int joy_btn
= 0;
Joystick.setButton(0, !a_btn);
Joystick.setButton(1, !b_btn);
Joystick.setButton(2, !c_btn);
Joystick.setButton(3, !d_btn);
Joystick.setButton(4, !e_btn);
Joystick.setButton(5, !f_btn);
Joystick.setButton(6, !joy_btn);
135
}
137
Our next step is to find a game to play. My choice is Super Mario :)
We've reached the final project in this book. Remember, what you can do
with Arduino and Tinylab is not limited to what's in this book; the only
limit is your imagination. I hope you've experienced the joy I felt while
preparing this book as you read through it. The pleasure of creating, in
my personal opinion, is an addictive feeling. I always hope your
curiosity and interest remain alive, so don't be afraid to create!
138
139
Source
• Wikipedia: en.wikipedia.org
• Robotistan Maker Blog: maker.robotistan.com
• Arduino Playground: playground.arduino.cc
• Adafruit Blog: learn.adafruit.com
• Fritzing is used for thdrawings: fritzing.org