Posts with «tutorial» label

3D Printed Gesture-Controlled Robot Arm is a Ton of Tutorials

Ever wanted your own gesture-controlled robot arm? [EbenKouao]’s DIY Arduino Robot Arm project covers all the bases involved, but even if a robot arm isn’t your jam, his project has plenty to learn from. Every part is carefully explained, complete with source code and a list of required hardware. This approach to documenting a project is great because it not only makes it easy to replicate the results, but it makes it simple to remix, modify, and reuse separate pieces as a reference for other work.

[EbenKouao] uses a 3D-printable robotic gripper, base, and arm design as the foundation of his build. Hobby servos and a single NEMA 17 stepper take care of the moving, and the wiring and motor driving is all carefully explained. Gesture control is done by wearing an articulated glove upon which is mounted flex sensors and MPU6050 accelerometers. These sensors detect the wearer’s movements and turn them into motion commands, which in turn get sent wirelessly from the glove to the robotic arm with HC-05 Bluetooth modules. We really dig [EbenKouao]’s idea of mounting the glove sensors to this slick 3D-printed articulated gauntlet frame, but using a regular glove would work, too. The latest version of the Arduino code can be found on the project’s GitHub repository.

Most of the parts can be 3D printed, how every part works together is carefully explained, and all of the hardware is easily sourced online, making this a very accessible project. Check out the full tutorial video and demonstration, embedded below.

3D printing has been a boon for many projects, especially those involving robotic arms. All kinds of robotic arm projects benefit from the advantages of 3D printing, from designs that focus on utility and function, to clever mechanical designs that reduce part count in unexpected ways.

Matrix and Joystick

For the original tutorial, please visit: https://arduinobasics.blogspot.com

 
 

Project Description

In this project, we will use a little joystick to move a pixel around an 8x8 LED matrix. The joystick has a built-in button, such that when you press down onto the joystick, the colour of the pixel will change from red to blue to green. This is a very simple project, however, controlling the matrix adds a certain level of complexity. You will need to understand binary notation and bit-shifting techniques to grasp the concept of this tutorial.

All of the parts used in this project can be obtained from digitspace.com

 
 
 
 

Libraries

The SPI library is required for this project. However, this library is built into the current version of the Arduino IDE. No additional download is required. Just make sure to include it at the top of the sketch.

 
 

Arduino Code

The Arduino IDE can be downloaded from the official Arduino website: here.
Copy and paste the following code into your Arduino IDE and upload it to the Arduino UNO.

 
 

Connections

 
 

Project Video

As you can see from the video above, the pixel changes colour when the button is pressed. The position of the pixel relates to the position of the joystick. The lag between the joystick movement and pixel movement is minimal, and very satisfying.

 
 

Conclusion

This was a very fun and satisfying project that showcases the interaction between a joystick and a 8x8 LED matrix with the help of an Arduino UNO. This project was sponsored by the kind people at digitspace. Without their sponsorship, this tutorial would not have been possible. Please visit their website for some nice deals on Arduino related products.

If you found this tutorial helpful, please consider supporting me by buying me a virtual coffee/beer.

$3.00 AUD only

Social Media

You can find me on various social networks:

Follow me on Twitter: ScottC @ArduinoBasics.
I can also be found on Instagram, Pinterest, and YouTube.
And if all else fails, I have a server on Discord.


ScottC 09 Mar 07:41
8x8  arduino  ce  clk  fun  joystick  led  matrix  module  mosi  pixel  programming  spi  sw  tutorial  uno  x  y  

Create your own Arduino Library

Project Description

In this short tutorial I will show you how to create your own Arduino Library. Making your own library seems daunting at first, but I will show you that it is not much harder than writing your own script/sketch. I would advise that you comment you code clearly, because when you come back to it in 5 years time, it will help to navigate you through your code at this time in history. Here we go, let's go through the process of creating a very simple Arduino library.

Parts Required

  • Arduino UNO or compatible board

Project Steps

Before we begin, there are a few questions you must ask yourself:

  1. What will the library be called ?
  2. What will the library do ?
  3. What are you trying to simplify?

For our library, these are the answers to the questions above:

  1. BlinkMe
  2. It will blink an LED attached to one of the digital pins
  3. The aim is to reduce the blink commands to a single line

Create a Folder

Create a folder on your computer which will be used to house all of the files in this project. Name the folder the same name as the library. In this case we will name it "BlinkMe". Make sure you use consistent naming throughout the tutorial. Capital and lowercase letters do matter.

Create the files

Using any text based editor (eg. notepad++, PSPad, Notepad2 etc), you will need to create 3 blank files:

  • The C++ file (BlinkMe.cpp) : Library code containing all of the functions
  • The Header file (BlinkMe.h): Contains the library function declarations
  • keywords.txt : Used for syntax highlighting within the Arduino IDE

I will tell you what you need to write inside each of these files, but make sure you have the blank BlinkMe.cpp, BlinkMe.h and keywords.txt files inside of the BlinkMe folder. Some people start by creating the header file first, but I personally like to start with the CPP file.
We will now look to populate the BlinkMe C++ file:

The C++ file (.cpp)

This file will contain all of the functions in your new library.
The first thing you will need to do is include the Arduino.h file. This will drag in all of the relevant Arduino code necessary for your library to function with an Arduino. And while we haven't yet created the header file (BlinkMe.h), we need to import that also. So the first two lines should be:

#include <Arduino.h>
 #include <BlinkMe.h>

The next section of code is the "constructor". This will be responsible for constructing the BlinkMe object. The BlinkMe object will allow you to call any of the public functions within the BlinkMe library. The constructor will allow us to define the default variables or constants.

BlinkMe::BlinkMe(){
    _dPin = 13;
 }

Sometimes we will want to blink an LED on a different pin. So we will create a function to set the pin that we would like use.

void setOUTPUT(int dPin){
    _dPin = dPin;
    pinMode(_dPin, OUTPUT);
 }

The only thing left is to create the useful part of the code. We will create a simple function that will blink the LED for a set duration. The function will have a parameter, which will be used to set the blink duration.

void blink(unsigned long delay_1){
    _delay_1 = delay_1;
    digitalWrite(_dPin, HIGH);
    delay(_delay_1);
    digitalWrite(_dPin, LOW);
    delay(_delay_1);
 }

Here is the complete "BlinkMe.cpp" file:

The Header file (.h)

The header file will be used to create the library function declarations. Open the "BlinkMe.h" file.
The first step is to check to make sure that the library is NOT already defined:

#ifndef BlinkMe_h

If it is not defined, then we must define the library:

#define BlinkMe_h

We then need to provide access to the standard Arduino types and constants

#include "Arduino.h"

And finally create the BlinkMe class:

//Create the class BlinkMe
class BlinkMe{
    public:
        BlinkMe();
        void setOUTPUT(int dPin);
        void blink(unsigned long delay_1);
    private:
        int _dPin;
        unsigned long _delay_1;
 };
#endif

Here is the complete header file:

keywords.txt (optional)

The keywords.txt file will contain the keywords for the library which will allow appropriate syntax highlighting. This file is optional, however it will highlight your classes or functions based on the keyword mapping.

  • LITERAL1: specifies constants (eg. HIGH, LOW,
  • KEYWORD1: specifies classes (eg. Serial)
  • KEYWORD2: specifies methods and functions (eg. analogRead, digitalWrite, delay)
  • KEYWORD3: specifies structures (eg. if, while, loop)
You need to make sure you use a single tab between the keyword and the "KEYWORD" mapping. In our example, BlinkMe is a class, so that would be a KEYWORD1. On the other hand, "blink" is a function, so that would be a KEYWORD2. So the keywords.txt file will contain the following text:

BlinkMe     KEYWORD1
setOUTPUT   KEYWORD2
blink       KEYWORD2

Example Sketch (optional)

It is often useful to include an sketch that provides an example of the library in use. It provides some context. If you plan to include the sketch in your library, then you must follow these simple rules:

  1. Create an "examples" folder.
  2. Create an example sketch, an place it within a folder of the same name as the sketch
  3. Place the sketch folder inside of the examples folder
You will end up with something like: examples/example_sketch/example_sketch.ino
In our case it will be: examples/blinkTest/blinkTest.ino

Here is the example sketch for this library (Save as blinkTest.ino):


The library

Here is a picture of the library contents:

And now the only thing left is to zip up the library folder and import it into the Arduino IDE. Use whatever program you want to zip up the BlinkMe folder, and note the location of the zip file. You need to import the zip file into the Arduino IDE:

  • Arduino IDE > Sketch > Include Library > Add .ZIP Library...
  • Select the library zip file you just created, and select "Open".
  • You can now use your library in the Arduino IDE.
  • Test it by running your example sketch: File > Examples > BlinkMe > blinkTest

Download

You can download the entire library here:
BlinkMe Library

Conclusion

In this tutorial, I showed you how to create a simple Arduino library. If you would like so see another example, have a look at my ToggleTimer library, which is very useful when trying to blink an LED without using a delay.You don't have to limit yourself to LEDs, you can use it for other projects where delay gets in the way. ToggleTimer is a non-blocking timer that toggles between two states.


If you found this tutorial helpful, please consider supporting me by buying me a virtual coffee/beer.

$3.00 AUD only

Social Media

You can find me on various social networks:

Follow me on Twitter: ScottC @ArduinoBasics.
I can also be found on Instagram, Pinterest, and YouTube.
And if all else fails, I have a server on Discord.


ScottC 29 Dec 10:09
arduino  blink  diy  led  library  tutorial  

Tutorial – Using the TCA9548A 1-to-8 I2C Multiplexer Breakout with Arduino

Now and again you may find yourself needing to use more than one device with the same I2C bus address with your Arduino.

Such as four OLEDs for a large display – or seven temperature sensors that are wired across a chicken hatchling coop.

These types of problems can be solved with the TCA9548A 1-to-8 I2C Multiplexer Breakout, and in this guide we’ll run through the how to make it happen with some example devices.

Getting Started

First, consider the TCA9548A itself. It is the gateway between your Arduino and eight separate I2C buses. You have a single bus on one side, connected to your Arduino.

On the other side of the TCA9548A, you have eight I2C buses, and only one of these can be connected to the Arduino at a time. For example (from the data sheet):

The TCA9548 can operate on voltages between 1.8 and 5V DC… and operate with devices that have operating voltages between 1.8 and 5V DC. This is very convenient, as (for example) you can use devices made for 3.3V operation with 5V Arduinos, or vice versa. Awesome. So let’s get started.

The breakout board includes inline header pins, which are not soldered to the board. So you need to do that. An easy way to line up the pins properly is to drop them into a soldereless breadboard, as such:

Then after a moment or two of soldering, you’re ready to use:

Next, insert your module into a solderless breadboard and wire it up as shown:

We are using the red and blue vertical strips on the breadboard as 5V and GND respectively. Finally, we connect the 5V and GND from the Arduino to the solderless breadboard, and A4/A5 to SDA/SCL respectively on the breakout board:

The electrical connections are as follows (Module — Arduino):

  • Vin to 5V
  • GND to GND
  • A0 to GND
  • A1 to GND
  • A2 to GND
  • SDA to A4
  • SCL to A5

Next, we consider the I2C bus address for the TCA9548A. Using the wiring setup shown above, the address is set to 0x70. You only need to change this if one of your other devices also has an address of 0x70, as shown in the next step.

Changing the I2C address of the TCA9548A

The bus address of the TCA9548A is changed using the connections to the A0, A1 and A2 pins. By default in the tutorial we use 0x70, by wiring A0~A2 to GND (known as LOW). Using the table below, you can reconfigure to an address between 0x70 and 0x77 by matching the inputs to HIGH (5V) or LOW (GND):

Testing 

Before we get too excited, now is a good time to test our wiring to ensure the Arduino can communicate with the TCA9548A. We’ll do this by running an I2C scanner sketch, which returns the bus address of a connected device.

Copy and paste this sketch into your Arduino IDE and upload it to your board. Then, open the serial monitor and set the data rate to 115200. You should be presented with something like the following:

As you can see, our scanner returned an address of 0x70, which matches the wiring described in the bus address table mentioned earlier. If you did not find success, unplug the Arduino from the computer and double-check your wiring – then try again.

Controlling the bus selector

Using the TCA9548A is your sketch is not complex at all, it only requires one step before using your I2C device as normal. That extra step is to instruct the TCA9548A to use one of the eight buses that it controls.

To do this, we send a byte of data to the TCA9548A’s bus register which represents which of the eight buses we want to use. Each bit of the byte is used to turn the bus on or off, with the MSB (most significant bit) for bus 7, and the LSB (least significant bit) for bus 0.

For example, if you sent:

0b00000001 (in binary) or 0 in decimal

… this would activate bus zero.

Or if you sent:

0b00010000 (in binary)

… this would activate bus five.

Once you select a bus, the TCA9548A channels all data in and out of the bus to the Arduino on the selected bus. You only need to send the bus selection data when you want to change buses. We’ll demonstrate that later.

So to make life easier, we can use a little function to easily select the required bus:

void TCA9548A(uint8_t bus)
{
  Wire.beginTransmission(0x70);  // TCA9548A address is 0x70
  Wire.write(1 << bus);          // send byte to select bus
  Wire.endTransmission();
}

This function accepts a bus number and places a “1” in the TCA9548A’s bus register matching our requirements. Then, you simply slip this function right before needing to access a device on a particular I2C bus. For example, a device on bus 0:

TCA9548A(0);

… or a device on bus 6:

TCA9548A(6);

A quick note about pull-up resistors

You still need to use pull-up resistors on the eight I2C buses eminating from the TCA9548A. If you’re using an assembled module, such as our example devices – they will have the resistors – so don’t panic.

If not, check the data sheets for your devices to determine the appropriate pull-up resistors value. If this information isn’t available, try 10k0 resistors.

Controlling our first device

Our first example device is the tiny 0.49″ OLED display. It is has four connections, which are wired as follows (OLED — TCA9548A/Arduino):

  • GND to GND
  • Vcc to Arduino 3.3V
  • CL to TCA9548A SC0 (bus #0, clock pin)
  • DA to TCA9548A SD1 (bus #0, data pin)

The OLED runs from 3.3V, so that’s why we’re powering it directly from the Arduino’s 3.3V pin.

Now, copy and upload this sketch to your Arduino, and after a moment the OLED will display some numbers counting down in various amounts:

So how did that work? We inserted out bus selection function at line 9 of the sketch, then called the function in at line 26 to tell the TCA9548A that we wanted to use I2C bus zero. Then the rest of the sketch used the OLED as normal.

Controlling two devices

Let’s add another device, a BMP180 barometric pressure sensor module. We’ll connect this to I2C bus number seven on the TCA5948A. There are four connections, which are wired as follows (BMP180 — TCA9548A/Arduino):

  • GND to GND
  • Vcc to Arduino 3.3V
  • CL to TCA9548A SC0 (bus #7, clock pin)
  • DA to TCA9548A SD1 (bus #7, data pin)

Now, copy and upload this sketch to the Arduino, and after a moment the OLED will display the ambient temperature from the BMP180 in whole degrees Celsius. This is demonstrated in the following video (finger is placed on the BMP180 for force a rise in temperature):

So how did that work? We set up the libraries and required code for the OLED, BMP180 and TCA5948A as usual.

We need to intialise the BMP180, so this is done at line 29 – where we select the I2C bus 7 before initiating the BMP180.

The the sketch operates. On line 40 we again request I2C bus 7 from the TCA9548A, then get the temperature from the BMP180.

On line 44 we request I2C bus 0 from the TCA9548A, and then display the temperature on the OLED. Then repeat.

A quick note about the reset pin

More advanced users will be happy to know they can reset the TCA9548A status, to recover from a bus-fault condition. To do this, simply drop the RESET pin LOW (that is, connect it to GND).

Where to from here? 

You can now understand through our worked example how easy it is to use the TCA9548A and access eight secondary I2C buses through the one bus from your Arduino. Don’t forget that the TCA9548A also does double-duty as a level converter, thereby increasing its value to you.

And that’s all for now. This post brought to you by pmdway.com – everything for makers and electronics enthusiasts, with free delivery worldwide.

To keep up to date with new posts at tronixstuff.com, please subscribe to the mailing list in the box on the right, or follow us on twitter @tronixstuff.

Tronixstuff 29 Oct 04:57

A tiny tiny 0.49″ 64 x 32 Graphic I2C OLED Display with Arduino

In this article we look at the tiny 0.49″ 64×32 graphic OLED from PMD Way. It is a compact and useful display, that only requires a small amount of time to get working with your Arduino or compatible board.

The purpose of this guide is to get your display successfully operating with your Arduino, so you can move forward and experiment and explore further types of operation with the display.

This includes installing the Arduino library, making a succesful board connection and running a demonstration sketch. So let’s get started!

Connecting the display to your Arduino

The display uses the I2C data bus for communication, and is a 5V and 3.3V-tolerant board.

Arduino Uno to Display

GND ---- GND (GND)
5V/3.3V- Vcc (power supply, can be 3.3V or 5V)
A5 ----- SCL (I2C bus clock)
A4 ----- SDA (I2C bus data)

I2C pinouts vary for other boards. Arduino Leonard uses D2/D3 for SDA and SCL or the separate pins to the left of D13. Arduino Mega uses D20/D21 for SDA and SCL. If you can’t find your I2C pins on other boards, email admin at tronixstuff dot com for assistance.

Installing the Arduino library

To install the library – simply open the Arduino IDE and select Manage Libraries… from the Tools menu. Enter “u8g2” in the search box, and after a moment it should appear in the results as shown in the image below. Click on the library then click “Install”:

After a moment the library will be installed and you can close that box.

Now it’s time to check everything necessary is working. Open a new sketch in the IDE, then copy and paste the following sketch into the IDE (you may find the “view raw” link at the end useful):

Your display should go through the demonstration of various font sizes and so on as shown in the video below:

You can see how we’ve used a different font in the sketch – at lines 19, 30 and 38. The list of fonts included with the library are provided at https://github.com/olikraus/u8g2/wiki/fntlistall.

Note that the initial location for each line of text (for example in line 20):

  u8g2.drawStr(0, 5, "Hello,");	 // write something to the internal memory 

The x and y coordinates (0,5) are for the bottom-left of the first character.

If you want to display values, not text – such as integers, use:

    u8g2.print();

… an example of which is show around line 49 in the example sketch.

Where to from here?

Now it’s time for you to explore the library reference guide which explains all the various functions available to create text and graphics on the display, as well as the fonts and so on. These can all be found on the right-hand side of the driver wiki page.

And that’s all for now. This post brought to you by pmdway.com – everything for makers and electronics enthusiasts, with free delivery worldwide.

To keep up to date with new posts at tronixstuff.com, please subscribe to the mailing list in the box on the right, or follow us on twitter @tronixstuff.

 

Tronixstuff 15 Oct 09:55
arduino  oled  tutorial  

Tutorial – Using the 0.96″ 80 x 160 Full Color IPS LCD Module with Arduino

The purpose of this guide is to get your 0.96″ color LCD display successfully operating with your Arduino, so you can move forward and experiment and explore further types of operation with the display. This includes installing the Arduino library, making a succesful board connection and running a demonstration sketch.

Although you can use the display with an Arduino Uno or other boad with an ATmega328-series microcontroller – this isn’t recommended for especially large projects. The library eats up a fair amount of flash memory – around 60% in most cases.

So if you’re running larger projects we recommend using an Arduino Mega or Due-compatible board due to the increased amount of flash memory in their host microcontrollers.

Installing the Arduino library

So let’s get started. We’ll first install the Arduino library then move on to hardware connection and then operating the display.

(As the display uses the ST7735S controller IC, you may be tempted to use the default TFT library included with the Arduino IDE – however it isn’t that reliable. Instead, please follow the instructions below). 

First – download the special Arduino library for your display and save it into your Downloads or a temp folder.

Next – open the Arduino IDE and select the Sketch > Include Library > Add .ZIP library option as shown below:

A dialog box will open – navigate to and select the zip file you downloaded earlier. After a moment or two the IDE will then install the library.

Please check that the library has been installed – to do this, select the Sketch > Include Library option in the IDE and scroll down the long menu until you see “ER-TFTM0.96-1” as shown below:

Once that has been successful, you can wire up your display.

Connecting the display to your Arduino

The display uses the SPI data bus for communication, and is a 3.3V board. You can use it with an Arduino or other 5V board as the logic is tolerant of higher voltages.

Arduino to Display

GND ----- GND (GND)
3.3V ---- Vcc (3.3V power supply)
D13 ----- SCL (SPI bus clock)
D11 ----- SDA (SPI bus data out from Arduino)
D10 ----- CS (SPI bus "Chip Select")
D9 ------ DC (Data instruction select pin)
D8 ------ RES (reset input)

If your Arduino has different pinouts than the Uno, locate the SPI pins for your board and modify as appropriate.

Demonstration sketch

Open a new sketch in the IDE, then copy and paste the following sketch into the IDE:

// https://pmdway.com/products/0-96-80-x-160-full-color-lcd-module
#include <UTFT.h>

// Declare which fonts we will be using
extern uint8_t SmallFont[];

// Initialize display
// Library only supports software SPI at this time
//NOTE: support  DUE , MEGA , UNO 
//SDI=11  SCL=13  /CS =10  /RST=8  D/C=9
UTFT myGLCD(ST7735S_4L_80160,11,13,10,8,9);    //LCD:  4Line  serial interface      SDI  SCL  /CS  /RST  D/C    NOTE:Only support  DUE   MEGA  UNO

// Declare which fonts we will be using
extern uint8_t BigFont[];

int color = 0;
word colorlist[] = {VGA_WHITE, VGA_BLACK, VGA_RED, VGA_BLUE, VGA_GREEN, VGA_FUCHSIA, VGA_YELLOW, VGA_AQUA};
int  bsize = 4;

void drawColorMarkerAndBrushSize(int col)
{
  myGLCD.setColor(VGA_BLACK);
  myGLCD.fillRect(25, 0, 31, 239);
  myGLCD.fillRect(myGLCD.getDisplayXSize()-31, 161, myGLCD.getDisplayXSize()-1, 191);
  myGLCD.setColor(VGA_WHITE);
  myGLCD.drawPixel(25, (col*30)+15);
  for (int i=1; i<7; i++)
    myGLCD.drawLine(25+i, ((col*30)+15)-i, 25+i, ((col*30)+15)+i);
  
  if (color==1)
    myGLCD.setColor(VGA_WHITE);
  else
    myGLCD.setColor(colorlist[col]);
  if (bsize==1)
    myGLCD.drawPixel(myGLCD.getDisplayXSize()-15, 177);
  else
    myGLCD.fillCircle(myGLCD.getDisplayXSize()-15, 177, bsize);
    
  myGLCD.setColor(colorlist[col]);
}
void setup()
{
  randomSeed(analogRead(0));
  
// Setup the LCD
  myGLCD.InitLCD();
  myGLCD.setFont(SmallFont);
}

void loop()
{
  int buf[158];
  int x, x2;
  int y, y2;
  int r;

// Clear the screen and draw the frame
  myGLCD.clrScr();

  myGLCD.setColor(255, 0, 0);
  myGLCD.fillRect(0, 0, 159, 13);
  myGLCD.setColor(64, 64, 64);
  myGLCD.fillRect(0, 114, 159, 127);
  myGLCD.setColor(255, 255, 255);
  myGLCD.setBackColor(255, 0, 0);
  myGLCD.print("pmdway.com.", CENTER, 1);
  myGLCD.setBackColor(64, 64, 64);
  myGLCD.setColor(255,255,0);
  myGLCD.print("pmdway.com", LEFT, 114);


  myGLCD.setColor(0, 0, 255);
  myGLCD.drawRect(0, 13, 159, 113);

// Draw crosshairs
  myGLCD.setColor(0, 0, 255);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.drawLine(79, 14, 79, 113);
  myGLCD.drawLine(1, 63, 158, 63);
  
 myGLCD.setColor(0, 0, 255);
 myGLCD.drawLine(0, 79, 159, 79);
 
  for (int i=9; i<150; i+=10)
    myGLCD.drawLine(i, 61, i, 65);
  for (int i=19; i<110; i+=10)
    myGLCD.drawLine(77, i, 81, i);
    

// Draw sin-, cos- and tan-lines  
  myGLCD.setColor(0,255,255);
  myGLCD.print("Sin", 5, 15);
  for (int i=1; i<158; i++)
  {
    myGLCD.drawPixel(i,63+(sin(((i*2.27)*3.14)/180)*40));
  }
  
  myGLCD.setColor(255,0,0);
  myGLCD.print("Cos", 5, 27);
  for (int i=1; i<158; i++)
  {
    myGLCD.drawPixel(i,63+(cos(((i*2.27)*3.14)/180)*40));
  }

  myGLCD.setColor(255,255,0);
  myGLCD.print("Tan", 5, 39);
  for (int i=1; i<158; i++)
  {
    myGLCD.drawPixel(i,63+(tan(((i*2.27)*3.14)/180)));
  }

  delay(2000);

  myGLCD.setColor(0,0,0);
  myGLCD.fillRect(1,14,158,113);
  myGLCD.setColor(0, 0, 255);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.drawLine(79, 14, 79, 113);
  myGLCD.drawLine(1, 63, 158, 63);

 myGLCD.setColor(0, 0, 255);
 myGLCD.drawLine(0, 79, 159, 79);  

// Draw a moving sinewave
  x=1;
  for (int i=1; i<(158*20); i++) 
  {
    x++;
    if (x==159)
      x=1;
    if (i>159)
    {
      if ((x==79)||(buf[x-1]==63))
        myGLCD.setColor(0,0,255);
      else
        myGLCD.setColor(0,0,0);
      myGLCD.drawPixel(x,buf[x-1]);
    }
    myGLCD.setColor(0,255,255);
    y=63+(sin(((i*2.5)*3.14)/180)*(40-(i / 100)));
    myGLCD.drawPixel(x,y);
    buf[x-1]=y;
  }

  delay(2000);
 
  myGLCD.setColor(0,0,0);
  myGLCD.fillRect(1,14,158,113);
  
 myGLCD.setColor(0, 0, 255);
 myGLCD.drawLine(0, 79, 159, 79);  

// Draw some filled rectangles
  for (int i=1; i<6; i++)
  {
    switch (i)
    {
      case 1:
        myGLCD.setColor(255,0,255);
        break;
      case 2:
        myGLCD.setColor(255,0,0);
        break;
      case 3:
        myGLCD.setColor(0,255,0);
        break;
      case 4:
        myGLCD.setColor(0,0,255);
        break;
      case 5:
        myGLCD.setColor(255,255,0);
        break;
    }
    myGLCD.fillRect(39+(i*10), 23+(i*10), 59+(i*10), 43+(i*10));
  }

  delay(2000);
  
  myGLCD.setColor(0,0,0);
  myGLCD.fillRect(1,14,158,113);
  myGLCD.setColor(0, 0, 255);
 myGLCD.drawLine(0, 79, 159, 79);   

// Draw some filled, rounded rectangles
  for (int i=1; i<6; i++)
  {
    switch (i)
    {
      case 1:
        myGLCD.setColor(255,0,255);
        break;
      case 2:
        myGLCD.setColor(255,0,0);
        break;
      case 3:
        myGLCD.setColor(0,255,0);
        break;
      case 4:
        myGLCD.setColor(0,0,255);
        break;
      case 5:
        myGLCD.setColor(255,255,0);
        break;
    }
    myGLCD.fillRoundRect(99-(i*10), 23+(i*10), 119-(i*10), 43+(i*10));
  }

  delay(2000);
  
  myGLCD.setColor(0,0,0);
  myGLCD.fillRect(1,14,158,113);

 myGLCD.setColor(0, 0, 255);
 myGLCD.drawLine(0, 79, 159, 79);  
// Draw some filled circles
  for (int i=1; i<6; i++)
  {
    switch (i)
    {
      case 1:
        myGLCD.setColor(255,0,255);
        break;
      case 2:
        myGLCD.setColor(255,0,0);
        break;
      case 3:
        myGLCD.setColor(0,255,0);
        break;
      case 4:
        myGLCD.setColor(0,0,255);
        break;
      case 5:
        myGLCD.setColor(255,255,0);
        break;
    }
    myGLCD.fillCircle(49+(i*10),33+(i*10), 15);
  }

  delay(2000);
    
  myGLCD.setColor(0,0,0);
  myGLCD.fillRect(1,14,158,113);
  
 myGLCD.setColor(0, 0, 255);
 myGLCD.drawLine(0, 79, 159, 79);    

// Draw some lines in a pattern
  myGLCD.setColor (255,0,0);
  for (int i=14; i<113; i+=5)
  {
    myGLCD.drawLine(1, i, (i*1.44)-10, 112);
  }
  myGLCD.setColor (255,0,0);
  for (int i=112; i>15; i-=5)
  {
    myGLCD.drawLine(158, i, (i*1.44)-12, 14);
  }
  myGLCD.setColor (0,255,255);
  for (int i=112; i>15; i-=5)
  {
    myGLCD.drawLine(1, i, 172-(i*1.44), 14);
  }
  myGLCD.setColor (0,255,255);
  for (int i=15; i<112; i+=5)
  {
    myGLCD.drawLine(158, i, 171-(i*1.44), 112);
  }

  delay(2000);
  
  myGLCD.setColor(0,0,0);
  myGLCD.fillRect(1,14,158,113);
  
 myGLCD.setColor(0, 0, 255);
 myGLCD.drawLine(0, 79, 159, 79);    

// Draw some random circles
  for (int i=0; i<100; i++)
  {
    myGLCD.setColor(random(255), random(255), random(255));
    x=22+random(116);
    y=35+random(57);
    r=random(20);
    myGLCD.drawCircle(x, y, r);
  }

  delay(2000);
  
  myGLCD.setColor(0,0,0);
  myGLCD.fillRect(1,14,158,113);
  
 myGLCD.setColor(0, 0, 255);
 myGLCD.drawLine(0, 79, 159, 79);    
  

// Draw some random rectangles
  for (int i=0; i<100; i++)
  {
    myGLCD.setColor(random(255), random(255), random(255));
    x=2+random(156);
    y=16+random(95);
    x2=2+random(156);
    y2=16+random(95);
    myGLCD.drawRect(x, y, x2, y2);
  }

  delay(2000);
  
  myGLCD.setColor(0,0,0);
  myGLCD.fillRect(1,14,158,113);
  
 myGLCD.setColor(0, 0, 255);
 myGLCD.drawLine(0, 79, 159, 79);    

// Draw some random rounded rectangles
  for (int i=0; i<100; i++)
  {
    myGLCD.setColor(random(255), random(255), random(255));
    x=2+random(156);
    y=16+random(95);
    x2=2+random(156);
    y2=16+random(95);
    myGLCD.drawRoundRect(x, y, x2, y2);
  }

  delay(2000);
  
  myGLCD.setColor(0,0,0);
  myGLCD.fillRect(1,14,158,113);
  
 myGLCD.setColor(0, 0, 255);
 myGLCD.drawLine(0, 79, 159, 79);  
 
  for (int i=0; i<100; i++)
  {
    myGLCD.setColor(random(255), random(255), random(255));
    x=2+random(156);
    y=16+random(95);
    x2=2+random(156);
    y2=16+random(95);
    myGLCD.drawLine(x, y, x2, y2);
  }

  delay(2000);
  
  myGLCD.setColor(0,0,0);
  myGLCD.fillRect(1,14,158,113);
  
 myGLCD.setColor(0, 0, 255);
 myGLCD.drawLine(0, 79, 159, 79);  
 
  for (int i=0; i<5000; i++)
  {
    myGLCD.setColor(random(255), random(255), random(255));
    myGLCD.drawPixel(2+random(156), 16+random(95));
  }

  delay(2000);

  myGLCD.fillScr(0, 0, 255);
  myGLCD.setColor(255, 0, 0);
  myGLCD.fillRoundRect(10, 17, 149, 72);
  
  myGLCD.setColor(255, 255, 255);
  myGLCD.setBackColor(255, 0, 0);
  myGLCD.print("That's it!", CENTER, 20);
  myGLCD.print("Restarting in a", CENTER, 45);
  myGLCD.print("few seconds...", CENTER, 57);
  
  myGLCD.setColor(0, 255, 0);
  myGLCD.setBackColor(0, 0, 255);
  myGLCD.print("Runtime: (msecs)", CENTER, 103);
  myGLCD.printNumI(millis(), CENTER, 115);

  delay (5000);   
}

 

Once you’re confident with the physical connection, upload the sketch. It should result with output as shown in the video below:

Now that you have succesfully run the demonstration sketch – where to from here?

The library used is based on the uTFT library by Henning Karlsen. You can find all the drawing and other commands in the user manual – so download the pdf and enjoy creating interesting displays.

This post brought to you by pmdway.com – everything for makers and electronics enthusiasts, with free delivery worldwide.

To keep up to date with new posts at tronixstuff.com, please subscribe to the mailing list in the box on the right, or follow us on twitter @tronixstuff.

Tronixstuff 29 Aug 09:15

Tutorial – Using the 0.96″ 128 x 64 Graphic I2C OLED Displays with Arduino

The purpose of this guide is to have an SSD1306-based OLED display successfully operating with your Arduino, so you can move forward and experiment and explore further types of operation with the display.

This includes installing the Arduino library, making a succesful board connection and running a demonstration sketch. So let’s get started!

Connecting the display to your Arduino

The display uses the I2C data bus for communication, and is a 5V and 3.3V-tolerant board.

Arduino Uno to Display

GND ---- GND (GND)
5V/3.3V- Vcc (power supply, can be 3.3V or 5V)
A5 ----- SCL (I2C bus clock)
A4 ----- SDA (I2C bus data)

I2C pinouts vary for other boards. Arduino Leonard uses D2/D3 for SDA and SCL or the separate pins to the left of D13. Arduino Mega uses D20/D21 for SDA and SCL. If you can’t find your I2C pins on other boards, ask your display supplier.

Installing the Arduino library

To install the library – simply open the Arduino IDE and select Manage Libraries… from the Tools menu. Enter “u8g2” in the search box, and after a moment it should appear in the results as shown in the image below. Click on the library then click “Install”:

After a moment the library will be installed and you can close that box.

Now it’s time to check everything necessary is working. Open a new sketch in the IDE, then copy and paste the following sketch into the IDE:

// Display > https://pmdway.com/products/0-96-128-64-graphic-oled-displays-i2c-or-spi-various-colors

#include <Arduino.h>
#include <U8x8lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

  U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);   

/*
  This example will probably not work with the SSD1606, because of the
  internal buffer swapping
*/

void setup(void)
{
  /* U8g2 Project: KS0108 Test Board */
  //pinMode(16, OUTPUT);
  //digitalWrite(16, 0);  

  /* U8g2 Project: Pax Instruments Shield: Enable Backlight */
  //pinMode(6, OUTPUT);
  //digitalWrite(6, 0); 

  u8x8.begin();
  //u8x8.setFlipMode(1);
}

void pre(void)
{
  u8x8.setFont(u8x8_font_amstrad_cpc_extended_f);    
  u8x8.clear();

  u8x8.inverse();
  u8x8.print(" U8x8 Library ");
  u8x8.setFont(u8x8_font_chroma48medium8_r);  
  u8x8.noInverse();
  u8x8.setCursor(0,1);
}

void draw_bar(uint8_t c, uint8_t is_inverse)
{ 
  uint8_t r;
  u8x8.setInverseFont(is_inverse);
  for( r = 0; r < u8x8.getRows(); r++ )
  {
    u8x8.setCursor(c, r);
    u8x8.print(" ");
  }
}

void draw_ascii_row(uint8_t r, int start)
{
  int a;
  uint8_t c;
  for( c = 0; c < u8x8.getCols(); c++ )
  {
    u8x8.setCursor(c,r);
    a = start + c;
    if ( a <= 255 )
      u8x8.write(a);
  }
}

void loop(void)
{
  int i;
  uint8_t c, r, d;
  pre();
  u8x8.print("github.com/");
  u8x8.setCursor(0,2);
  u8x8.print("olikraus/u8g2");
  delay(2000);
  u8x8.setCursor(0,3);
  u8x8.print("Tile size:");
  u8x8.print((int)u8x8.getCols());
  u8x8.print("x");
  u8x8.print((int)u8x8.getRows());
  
  delay(2000);
   
  pre();
  for( i = 19; i > 0; i-- )
  {
    u8x8.setCursor(3,2);
    u8x8.print(i);
    u8x8.print("  ");
    delay(150);
  }
  
  draw_bar(0, 1);
  for( c = 1; c < u8x8.getCols(); c++ )
  {
    draw_bar(c, 1);
    draw_bar(c-1, 0);
    delay(50);
  }
  draw_bar(u8x8.getCols()-1, 0);

  pre();
  u8x8.setFont(u8x8_font_amstrad_cpc_extended_f); 
  for( d = 0; d < 8; d ++ )
  {
    for( r = 1; r < u8x8.getRows(); r++ )
    {
      draw_ascii_row(r, (r-1+d)*u8x8.getCols() + 32);
    }
    delay(400);
  }

  draw_bar(u8x8.getCols()-1, 1);
  for( c = u8x8.getCols()-1; c > 0; c--)
  {
    draw_bar(c-1, 1);
    draw_bar(c, 0);
    delay(50);
  }
  draw_bar(0, 0);

  pre();
  u8x8.drawString(0, 2, "Small");
  u8x8.draw2x2String(0, 5, "Scale Up");
  delay(3000);

  pre();
  u8x8.drawString(0, 2, "Small");
  u8x8.setFont(u8x8_font_px437wyse700b_2x2_r);
  u8x8.drawString(0, 5, "2x2 Font");
  delay(3000);

  pre();
  u8x8.drawString(0, 1, "3x6 Font");
  u8x8.setFont(u8x8_font_inb33_3x6_n);
  for(i = 0; i < 100; i++ )
  {
    u8x8.setCursor(0, 2);
    u8x8.print(i);      // Arduino Print function
    delay(10);
  }
  for(i = 0; i < 100; i++ )
  {
    u8x8.drawString(0, 2, u8x8_u16toa(i, 5)); // U8g2 Build-In functions
    delay(10);    
  }

  pre();
  u8x8.drawString(0, 2, "Weather");
  u8x8.setFont(u8x8_font_open_iconic_weather_4x4);
  for(c = 0; c < 6; c++ )
  {
    u8x8.drawGlyph(0, 4, '@'+c);
    delay(300);
  }
  

  pre();
  u8x8.print("print \\n\n");
  delay(500);
  u8x8.println("println");
  delay(500);
  u8x8.println("done");
  delay(1500);

  pre();
  u8x8.fillDisplay();
  for( r = 0; r < u8x8.getRows(); r++ )
  {
    u8x8.clearLine(r);
    delay(100);
  }
  delay(1000);
}

Your display should go through the demonstration of various things as shown in the video below:

If the display did not work – you may need to manually set the I2C bus address. To do this, wire up your OLED then run this sketch (open the serial monitor for results). It’s an I2C scanner tool that will return the I2C bus display. 

Then use the following line in void setup():

u8x8.setI2CAddress(address)

Replace u8x8 with your display reference, and address with the I2C bus address (for example. 0x17).

Moving on…

By now you have an idea of what is possible with these great-value displays.

Now your display is connected and working, it’s time to delve deeper into the library and the various modes of operations. There are three, and they are described in the library documentation – click here to review them

Whenever you use one of the three modes mentioned above, you need to use one of the following constructor lines:

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // full buffer mode

U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); // 8x8 character mode

U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // page buffer mode

Match the mode you wish to use with one of the constructors above. For example, in the demonstration sketch you ran earlier, we used the 8×8 character mode constructor in line 14.

Where to from here?

Now it’s time for you to explore the library reference guide which explains all the various functions available to create text and graphics on the display, as well as the fonts and so on. These can all be found on the right-hand side of the driver wiki page.

This post brought to you by pmdway.com – everything for makers and electronics enthusiasts, with free delivery worldwide.

To keep up to date with new posts at tronixstuff.com, please subscribe to the mailing list in the box on the right, or follow us on twitter @tronixstuff.

Tronixstuff 29 Aug 08:38

Tutorial – LED Real Time Clock Temperature Sensor Shield for Arduino

In this tutorial we look at how to use the neat LED Real Time Clock Temperature Sensor Shield for Arduino from PMD Way. That’s a bit of a mouthful, however the shield does offer the following:

  • four digit, seven-segment LED display
  • DS1307 real-time clock IC
  • three buttons
  • four LEDs
  • a active buzzer
  • a light-dependent resistor (LDR)
  • and a thermistor for measuring ambient temperature

The shield also arrives fully-assembled , so you can just plug it into your Arduino Uno or compatible board. Neat, beginners will love that. So let’s get started, by showing how each function can be used – then some example projects. In no particular order…

The buzzer

A high-pitched active buzzer is connected to digital pin D6 – which can be turned on and off with a simple digitalWrite() function. So let’s do that now, for example:

void setup() {
  // buzzer on digital pin 6
  pinMode(6, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(6, HIGH);   // turn the buzzer on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(6, LOW);    // turn the buzzer off by making the voltage LOW
  delay(1000);                       // wait for a second
}

If there is a white sticker over your buzzer, remove it before uploading the sketch. Now for a quick video demonstration. Turn down your volume before playback.

The LEDs

Our shield has four LEDs, as shown below:

They’re labelled D1 through to D4, with D1 on the right-hand side. They are wired to digital outputs D2, D3, D4 and D5 respectively. Again, they can be used with digitalWrite() – so let’s do that now with a quick demonstration of some blinky goodness. Our sketch turns the LEDs on and off in sequential order. You can change the delay by altering the variable x:

void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(2, OUTPUT); // LED 1
  pinMode(3, OUTPUT); // LED 2
  pinMode(4, OUTPUT); // LED 3
  pinMode(5, OUTPUT); // LED 4
}

int x = 200;

void loop() {
  digitalWrite(2, HIGH);    // turn on LED1
  delay(x);
  digitalWrite(2, LOW);    // turn off LED1. Process repeats for the other three LEDs
  digitalWrite(3, HIGH);
  delay(x);
  digitalWrite(3, LOW);
  digitalWrite(4, HIGH);
  delay(x);
  digitalWrite(4, LOW);
  digitalWrite(5, HIGH);
  delay(x);
  digitalWrite(5, LOW);
}

And in action:

The Buttons

It is now time to pay attention to the three large buttons on the bottom-left of the shield. They look imposing however are just normal buttons, and from right-to-left are connected to digital pins D9, D10 and D11:

They are, however, wired without external pull-up or pull-down resistors so when initialising them in your Arduino sketch you need to activate the digital input’s internal pull-up resistor inside the microcontroller using:

pinMode(pin, INPUT_PULLUP);

Due to this, buttons are by default HIGH when not pressed. So when you press a button, they return LOW. The following sketch demonstrates the use of the buttons by lighting LEDs when pressed:

void setup() {
  // initalise digital pins for LEDs as outputs
  pinMode(2, OUTPUT); // LED 1
  pinMode(3, OUTPUT); // LED 2
  pinMode(4, OUTPUT); // LED 3

  // initalise digital pins for buttons as inputs
  // and initialise internal pullups
  pinMode(9, INPUT_PULLUP); // button K1
  pinMode(10, INPUT_PULLUP); // button K2
  pinMode(11, INPUT_PULLUP); // button K3
}

void loop()
{
  if (digitalRead(9) == LOW)
  {
    digitalWrite(2, HIGH);
    delay(10);
    digitalWrite(2, LOW);
  }

  if (digitalRead(10) == LOW)
  {
    digitalWrite(3, HIGH);
    delay(10);
    digitalWrite(3, LOW);
  }

  if (digitalRead(11) == LOW)
  {
    digitalWrite(4, HIGH);
    delay(10);
    digitalWrite(4, LOW);
  }
}

You can see these in action via the following video:

The Numerical LED Display

Our shield has a nice red four-digit, seven-segment LED clock display. We call it a clock display as there are colon LEDs between the second and third digit, just as a digital clock would usually have:

The display is controlled by a special IC, the Titan Micro TM1636:

The TM1636 itself is an interesting part, so we’ll explain that in a separate tutorial in the near future. For now, back to the shield.

To control the LED display we need to install an Arduino library. In fact the shield needs four, so you can install them all at once now. Download the .zip file from here. Then expand that into your local download directory – it contains four library folders. You can then install them one at a time using the Arduino IDE’s Sketch > Include library > Add .zip library… command:

The supplied library offers five functions used to control the display.

.num(x);

…this displays a positive integer (whole number) between 0 and 9999.

.display(p,d);

… this shows a digit d in location p (locations from left to right are 3, 2, 1, 0)

.time(h,m)

… this is used to display time data (hours, minutes) easily. h is hours, m is minutes

.pointOn();
.pointOff();

… these turn the colon on … and off. And finally:

.clear();

… which clears the display to all off. At the start of the sketch, we need to use the library and initiate the instance of the display by inserting the following lines:

#include <TTSDisplay.h>
TTSDisplay rtcshield;

Don’t panic – the following sketch demonstrates the five functions described above:

#include <TTSDisplay.h>
TTSDisplay rtcshield;

int a = 0;
int b = 0;

void setup() {}

void loop()
{
  // display some numbers
  for (a = 4921; a < 5101; a++)
  {
    rtcshield.num(a);
    delay(10);
  }

  // clear display
  rtcshield.clear();

  // display individual digits
  for (a = 3; a >= 0; --a)
  {
    rtcshield.display(a, a);
    delay(1000);
    rtcshield.clear();
  }
  for (a = 3; a >= 0; --a)
  {
    rtcshield.display(a, a);
    delay(1000);
    rtcshield.clear();
  }

  // turn the colon and off
  for (a = 0; a < 5; a++)
  {
    rtcshield.pointOn();
    delay(500);
    rtcshield.pointOff();
    delay(500);
  }

  // demo the time display function
  rtcshield.pointOn();
  rtcshield.time(11, 57);
  delay(1000);
  rtcshield.time(11, 58);
  delay(1000);
  rtcshield.time(11, 59);
  delay(1000);
  rtcshield.time(12, 00);
  delay(1000);
}

And you can see it in action through the video below:

The LDR (Light Dependent Resistor)

LDRs are useful for giving basic light level measurements, and our shield has one connected to analog input pin A1. It’s the two-legged item with the squiggle on top as shown below:

The resistance of LDRs change with light levels – the greater the light, the less the resistance. Thus by measuring the voltage of a current through the LDR with an analog input pin – you can get a numerical value proportional to the ambient light level. And that’s just what the following sketch does:

#include <TTSDisplay.h>
TTSDisplay rtcshield;

int a = 0;

void setup() {}
void loop()
{
  // read value of analog input
  a = analogRead(A1);
  // show value on display
  rtcshield.num(a);
  delay(100);
}

The Thermistor

A thermistor is a resistor whose resistance is relative to the ambient temperature. As the temperature increases, their resistance decreases. It’s the black part to the left of the LDR in the image below:

We can use this relationship between temperature and resistance to determine the ambient temperature. To keep things simple we won’t go into the theory – instead, just show you how to get a reading.

The thermistor circuit on our shield has the output connected to analog input zero, and we can use the library installed earlier to take care of the mathematics. Which just leaves us with the functions.

At the start of the sketch, we need to use the library and initiate the instance of the thermistor by inserting the following lines:

#include <TTSTemp.h>
TTSTemp temp;

… then use the following which returns a positive integer containing the temperature (so no freezing cold environments):

.get();

For our example, we’ll get the temperature and show it on the numerical display:

#include <TTSDisplay.h>
#include <TTSTemp.h>

TTSTemp temp;
TTSDisplay rtcshield;

int a = 0;

void setup() {}

void loop() {

  a = temp.get();
  rtcshield.num(a);
  delay(500);
}

And our thermometer in action. No video this time… a nice 24 degrees C in the office:

The Real-Time Clock 

Our shield is fitted with a DS1307 real-time clock IC circuit and backup battery holder. If you insert a CR1220 battery, the RTC will remember the settings even if you remove the shield from the Arduino or if there’s a power blackout, board reset etc:

The DS1307 is incredibly popular and used in many projects and found on many inexpensive breakout boards. We have a separate tutorial on how to use the DS1307, so instead of repeating ourselves – please visit our specific DS1307 Arduino tutorial, then return when finished.

Where to from here? 

We can image there are many practical uses for this shield, which will not only improve your Arduino coding skills but also have some useful applications. An example is given below, that you can use for learning or fun.

Temperature Alarm

This projects turns the shield into a temperature monitor – you can select a lower and upper temperature, and if the temperature goes outside that range the buzzer can sound until you press it.

Here’s the sketch:

#include <TTSDisplay.h>
#include <TTSTemp.h>

TTSTemp temp;
TTSDisplay rtcshield;

boolean alarmOnOff = false;
int highTemp = 40;
int lowTemp = 10;
int currentTemp;

void LEDsoff()
{
  // function to turn all alarm high/low LEDs off
  digitalWrite(2, LOW);
  digitalWrite(4, LOW);
}

void setup() {
  // initalise digital pins for LEDs and buzzer as outputs
  pinMode(2, OUTPUT); // LED 1
  pinMode(3, OUTPUT); // LED 2
  pinMode(4, OUTPUT); // LED 3
  pinMode(5, OUTPUT); // LED 4
  pinMode(6, OUTPUT); // buzzer

  // initalise digital pins for buttons as inputs
  // and initialise internal pullups
  pinMode(9, INPUT_PULLUP); // button K1
  pinMode(10, INPUT_PULLUP); // button K2
  pinMode(11, INPUT_PULLUP); // button K3
}

void loop()
{
  // get current temperature
  currentTemp = temp.get();

  // if current temperature is within set limts
  // show temperature on display

  if (currentTemp >= lowTemp || currentTemp <= highTemp)
    // if ambient temperature is less than high boundary
    // OR if ambient temperature is grater than low boundary
    // all is well
  {
    LEDsoff(); // turn off LEDs
    rtcshield.num(currentTemp);
  }

  // if current temperature is above set high bounday, show red LED and
  // show temperature on display
  // turn on buzzer if alarm is set to on (button K3)

  if (currentTemp > highTemp)
  {
    LEDsoff(); // turn off LEDs
    digitalWrite(4, HIGH); // turn on red LED
    rtcshield.num(currentTemp);
    if (alarmOnOff == true) {
      digitalWrite(6, HIGH); // buzzer on }
    }
  }

  // if current temperature is below set lower boundary, show blue LED and
  // show temperature on display
  // turn on buzzer if alarm is set to on (button K3)

  if (currentTemp < lowTemp)
  {
    LEDsoff(); // turn off LEDs
    digitalWrite(2, HIGH); // turn on blue LED
    rtcshield.num(currentTemp);
    if (alarmOnOff == true)
    {
      digitalWrite(6, HIGH); // buzzer on }
    }
  }
  // --------turn alarm on or off-----------------------------------------------------
  if (digitalRead(11) == LOW) // turn alarm on or off
  {
    alarmOnOff = !alarmOnOff;
    if (alarmOnOff == 0) {
      digitalWrite(6, LOW); // turn off buzzer
      digitalWrite(5, LOW); // turn off alarm on LED
    }
    // if alarm is set to on, turn LED on to indicate this
    if (alarmOnOff == 1)
    {
      digitalWrite(5, HIGH);
    }
    delay(300); // software debounce
  }
  // --------set low temperature------------------------------------------------------
  if (digitalRead(10) == LOW) // set low temperature. If temp falls below this value, activate alarm
  {
    // clear display and turn on blue LED to indicate user is setting lower boundary
    rtcshield.clear();
    digitalWrite(2, HIGH); // turn on blue LED
    rtcshield.num(lowTemp);

    // user can press buttons K2 and K1 to decrease/increase lower boundary.
    // once user presses button K3, lower boundary is locked in and unit goes
    // back to normal state

    while (digitalRead(11) != LOW)
      // repeat the following code until the user presses button K3
    {
      if (digitalRead(10) == LOW) // if button K2 pressed
      {
        --lowTemp; // subtract one from lower boundary
        // display new value. If this falls below zero, won't display. You can add checks for this yourself :)
        rtcshield.num(lowTemp);
      }
      if (digitalRead(9) == LOW) // if button K3 pressed
      {
        lowTemp++; // add one to lower boundary
        // display new value. If this exceeds 9999, won't display. You can add checks for this yourself :)
        rtcshield.num(lowTemp);
      }
      delay(300); // for switch debounce
    }
    digitalWrite(2, LOW); // turn off blue LED
  }
  // --------set high temperature-----------------------------------------------------
  if (digitalRead(9) == LOW) // set high temperature. If temp exceeds this value, activate alarm
  {

    // clear display and turn on red LED to indicate user is setting lower boundary
    rtcshield.clear();
    digitalWrite(4, HIGH); // turn on red LED
    rtcshield.num(highTemp);

    // user can press buttons K2 and K1 to decrease/increase upper boundary.
    // once user presses button K3, upper boundary is locked in and unit goes
    // back to normal state

    while (digitalRead(11) != LOW)
      // repeat the following code until the user presses button K3
    {
      if (digitalRead(10) == LOW) // if button K2 pressed
      {
        --highTemp; // subtract one from upper boundary
        // display new value. If this falls below zero, won't display. You can add checks for this yourself :)
        rtcshield.num(highTemp);
      }
      if (digitalRead(9) == LOW) // if button K3 pressed
      {
        highTemp++; // add one to upper boundary
        // display new value. If this exceeds 9999, won't display. You can add checks for this yourself :)
        rtcshield.num(highTemp);
      }
      delay(300); // for switch debounce
    }
    digitalWrite(4, LOW); // turn off red LED
  }
}

Operating instructions:

  • To set lower temperature, – press button K2. Blue LED turns on. Use buttons K2 and K1 to select temperature, then press K3 to lock it in. Blue LED turns off.
  • To set upper temperature – press button K1. Red LED turns on. Use buttons K2 and K1 to select temperature, then press K3 to lock it in. Red LED turns off.
  • If temperature drops below lower or exceeds upper temperature, the blue or red LED will come on.
  • You can have the buzzer sound when the alarm activates – to do this, press K3. When the buzzer mode is on, LED D4 will be on. You can turn buzzer off after it activates by pressing K3.
  • Display will show ambient temperature during normal operation.

You can see this in action via the video below:

Conclusion

This is a fun and useful shield – especially for beginners. It offers a lot of fun and options without any difficult coding or soldering – it’s easy to find success with the shield and increase your motivation to learn more and make more.

You can be serious with a clock, or annoy people with the buzzer. And at the time of writing you can have one for US$14.95, delivered. So go forth and create something.

A little research has shown that this shield was based from a product by Seeed, who discontinued it from sale. I’d like to thank them for the library.

This post brought to you by pmdway.com – everything for makers and electronics enthusiasts, with free delivery worldwide.

To keep up to date with new posts at tronixstuff.com, please subscribe to the mailing list in the box on the right, or follow us on twitter @tronixstuff.

Maker Display to Ubidots MQTT button


See the original project on the ArduinoBasics Blog

 
 

Description

This tutorial will show you how to create a simple MQTT connection to Ubidots. You will also learn to configure the necessary MQTT subscription to a button on the Ubidots dashboard, and control a Maker Display (ESP-12E compitible board) from anywhere in the world. The process may seem a bit daunting at first, but hopefully by the end of this tutorial, you will feel comfortable creating your own Ubidots MQTT subscriptions.

 
 

Parts Required

  1. Maker Display 2 or Node MCU (ESP-12E) module
  2. NOVA programmer
  3. USB mini-B cable
  4. WiFi internet connection
  5. Ubidots account (free)

The Maker display 2 has an inbuilt ESP8266MCD WiFi module which will be used to create the MQTT connection to the Ubidots broker (online).

 
 

Ubidots Setup

This tutorial requires a FREE Ubidots account.
Go to this site to sign up: https://ubidots.com/education/
Once signed up, you will need to configure Ubidots using the following instructions.

Create a device

  1. Select: Devices > Devices
  2. Select: Create a Device (button)
  3. Select: Blank (from the available device list)
  4. Enter the "Maker Display" into the "Device name" field, "maker-display" into the "Device label" field, and click on "Create" button
  5. Select: the "Maker Display" device

Create a variable

  1. Select: "Add Variable" button, then select "Raw" from the two available options.
  2. Select: the "New Variable" to edit it
  3. Change the name to "Button 1", the description to "button1 variable" and the API label to "button1"

Create a dashboard

  1. Select: Data > Dashboard
  2. Select: Add new dashboard
  3. Change the Name to "Maker Display Dashboard", and update the date format to a suitable format. (press tick)

Add a Widget

  1. Select: "Add new Widget"
  2. Select: Switch (from the available widgets)
  3. Select: Add Variables
  4. Select: Maker Display > Button1 > tick
  5. Accept the default values for the Switch (Off=0, On=1), and press the tick
  6. You should now have a button called "Button1" associated with the "Maker Display" device, visible on the "Maker Display Dashboard"
  7. The button is "off".

Create a Ubidots TOKEN

  1. Select: "API Credentials" from the profile drop-down box in the top right corner.
  2. Click the blue "More" - located below the Tokens section
  3. Click on the round blue (+) button to create a NEW TOKEN.
  4. Change the name to "Maker Display Token" - and keep a record of TOKEN value. There is an icon which will allow you copy the TOKEN value to the clipboard.

Take note of key information

Now that the Ubidots Dashboard is set up, you will need to ensure you have 3 sets of information to insert into the code.

  1. Maker Display Token Value
  2. Button1 API label: "button1"
  3. Maker Display Device API Label: "maker-display"

 
 

Ubidots slideshow of the setup process

Slide Set created by Scott C with GoConqr

 
 

Arduino IDE

While there are many Arduino IDE alternatives out there, I would recommend that you use the official Arduino IDE for this project. I used the official Arduino IDE app (v1.8.5) for Windows 10.
Make sure to get the most up-to-date version for your operating system here.

Additional Boards Manager URLS

Make sure to add the following URLs to your "additional boards manager URL" setting:
  • File > Preferences > Additional Boards Manager URLS:
    • http://arduino.esp8266.com/stable/package_esp8266com_index.json
    • https://dl.espressif.com/dl/package_esp32_index.json

Select Tools > Board: "NodeMCU 1.0 (ESP-12E Module)" board.
Then check that you have the following settings:

  • Board:"NodeMCU 1.0 (ESP-12E Module)"
  • Flash Size:"4M(no SPIFFS)"
  • Debug port:"Disabled"
  • Debug Level:"None"
  • IwIP Variant:"v2 Lower Memory"
  • VTables:"Flash"
  • CPU Frequency:"80 MHz"
  • Exceptions:"Disabled"
  • Upload Speed:"115200"
  • Erase Flash:"Only Sketch"
  • Port: (Select your port)
  • Get Board Info
  • Programmer:"AVRISP mkII"


 
 

Libraries required

This tutorial makes use of two libraries: ESP8266WiFi.h and PubSubClient.h.

  • ESP8266WiFi.h : This library is required for the WiFi connection to the internet. More info.
  • PubSubClient.h : Is used to create an MQTT Client to handle the communication between the Ubidots MQTT broker and the Maker Display2 (or ESP-12E).

Both libraries can be installed via the library manager: Sketch > Include library > Manage Libraries



 
 
 
 

Arduino Code

Connect the NOVA programmer to the Maker Display 2

Remember that you will need to insert the 3 bits of information from the "Ubidots" section, into the code. You will also need to know your WiFI SSID name, and password. Copy the code below into the Arduino IDE, make the necessary changes in the sketch to reflect the API labels and tokens from your Ubidots account. Connect the USB cable to the computer, select the correct COM port (Tools > Port), then upload the code to the Maker display board.

The code is available on my GitHub repository. Or you can have a look at the fully commented code below.

 
 

Open the Serial monitor (ctrl + shift + M), ensure the Baud is set to 9600, and then press the button on the Ubidots Maker Display Dashboard. You should see messages appear in the Serial monitor that correspond with the state of the button.

 
 

Code Explained

A number of different information sources were utilised to construct the code above. These sources were acknowledged within. As noted before, the code uses two libraries, one to simplify the WiFi connection to the internet, and the other to simplify the connection of the Maker Display to the Ubidots MQTT broker.

setup()

The setup() function is used to establish the WiFi connection, set the MQTT broker, and define the callback function - which will be called each time the button on the Ubidots dashboard is pressed.

loop()

The loop() function is responsible for connecting to the MQTT broker, and polling for messages from the MQTT broker using the client.loop() function.

callback()

The callback() function first checks the "topic" message coming from the MQTT broker, and compares it to the buttonTopic variable. The buttonTopic variable in this sketch is equal to "/v1.6/devices/maker-display/button1/lv". You will notice that the variable is constructed using the "device API label", and the "button API label". The other components of the buttonTopic are always the same. eg.

"/v1.6/devices/{device label}/{variable label}/lv"

This comparison allows us to differentiate this particular button from other potential components on the Ubidots dashboard. The value of the button (on=1/off=0), is transmitted from the MQTT broker each time the button is pressed on the Ubidots Maker Display dashboard. It is captured by the "payload" variable in the callback function. If the payload variable is equal to 1 (on), then a Serial message will be transmitted "BUTTON ON". If the payload variable is equal to 0 (off), then a Serial message will be transmitted "BUTTON OFF". You will be able to see this message come through by opening the Serial Monitor (ctrl+shift+M) within the Arduino IDE.

MQTTconnect()

The MQTTconnect() function is responsible for connecting to the MQTT broker. It requires a Ubidots TOKEN, a unique MQTT client name and a pre-defined port (1883). In order to receive messages from the button on the Ubidots Maker Display dashboard, we need to subscribe to button. But first we need to construct the string location of the button variable.  
 
We do this using the sprintf() function.  
 
If you would like to learn more about the sprintf function have a look at my tutorial here.  
 
The sprintf function is used to construct the string in a specific format, and in this case it uses the DEVICE_LABEL, and VARIABLE_LABEL1, and assigns the string to the buttonTopic variable. Once constructed the buttonTopic variable is used to subscribe to the button on the Ubidots dashboard.

The program is instructed to retry the connection attempt every 2 seconds if it fails to connect for any reason.

 
 

Project in Action


 
 

Conclusion

Setting up the Ubidots dashboard and the Arduino IDE takes up the majority of the time in this project. Once all the configurations are made, the rest is pretty simple. I hope by the end of this tutorial, you will have learnt how to create a button on a Ubidots dashboard, and interface it with a Maker Display (ESP-12 compatible board).

While there are plenty of examples on the Ubidots website that will show you how to push data to the dashboard, I found that the opposite was not true. There are limited examples that show you how to control your device from a Ubidots widget. I know that this example is not that exciting, but hopefully, you understand the significance of the information, and understand how easy it would be to modify the sketch above to make it more exciting. However, I did not want to over-complicate the tutorial with other complexities. Perhaps in the next tutorial we will use the information gained here, to do something a bit more thrilling. But at least now you know the basics. We can now:

  • Program a Maker Display
  • Add widgets to a Ubidots dashboard
  • Control the Maker Display using widgets from a Ubidots dashboard (using MQTT)

If you found this tutorial helpful, please consider supporting me by buying me a virtual coffee/beer.

$3.00 AUD only
 

Social Media

You can find me on various social networks:

Follow me on Twitter: ScottC @ArduinoBasics.
I can also be found on Instagram, Pinterest, and YouTube.
And if all else fails, I have a server on Discord.



             

sprintf function

Description

This tutorial will help you to understand the sprintf function, and how to use it. Essentially, the sprintf function allows you to construct a string using a pre-formatted string template to which you can insert variables at pre-defined locations. The sprintf function will "compile" the string and assign it to a char array. All you have to do is make sure that the char array is large enough to hold all of the characters in the string. The best way to understand the sprintf function is with examples. And luckily, I have examples. What are we waiting for ? Let's dive in.

Parts Required: an Arduino and a USB cable.

 
 

sprintf ( char* array,   const char* strTemplate,   var1...);

 
 

Arduino IDE

While there are many Arduino IDE alternatives out there, I would recommend that you use the official Arduino IDE for this project. I used the official Arduino IDE app (v1.8.5) for Windows 10.
Make sure to get the most up-to-date version for your operating system here.


 
 

Arduino Code

The code below will show you how to use the sprintf function and includes a number of different format specifiers to play with. In each case the sprintf function writes to the "data" character array, and subsequently sends it through to the Serial monitor. The string template helps to construct the data output, allowing you to insert variables at specific locations within the text. The format of the variable is defined by the "format specifier" used in the sprintf function. The format specifier is always prefixed with a percentage sign (%).

 
 

Serial Monitor Output

  1. Upload the code to the Arduino.
  2. Open the Serial monitor in the Arduino IDE (Ctrl+Shift+M).
  3. Ensure that you have set the baud rate in the Serial monitor to 9600.
  4. You should see the following output:

 

The sprintf function requires that you have a character array to store the output. In the example code above, the output is stored in the "data" character array. It also requires a template that tells the function where to insert the variables. As you can see from the table below, the variables will be formatted based on the format specifier used. The format specifier can be quite useful for numeric conversions. Eg. decimal to hex conversions.

 
 

Format Specifiers

Some of the different format specifiers that can be used with the sprinf function are listed below.

Conclusion

Now that you know all about the sprintf function, I hope it will inspire you to use it in your own projects. Please let me know in the comments below how you use the sprintf function, and whether there was anything that you feel I failed to mention in this tutorial.
Happy Coding !!

 
 

If you found this tutorial helpful, please consider supporting me by buying me a virtual coffee/beer.

$3.00 AUD only
 

Social Media

You can find me on various social networks:

Follow me on Twitter: ScottC @ArduinoBasics.
I can also be found on Instagram, Pinterest, and YouTube.
And if all else fails, I have a server on Discord.