The Nerd with Arduino IoT Bundle

Create your own IoT pet with Arduino and the Arduino Cloud!

Components and Supplies

Apps and Online Services

About This Project

Create a desktop pet with the help of the Arduino Cloud!

The Nerd is a desktop electronic pet that survives by eating and some sunlight. For it to thrive, you must feed it periodically and expose it to sunlight. If it is running out of food, it will communicate an SOS in Morse code using its built-in piezo speaker.

In a Nutshell

The Nerd will need food which you can give it by pressing its button. Otherwise, it will die. The nerd will be connected to the Arduino Cloud, where we can visualize the amount of food the Nerd has and the level of light it is in. If the Nerd runs out of food, it will die dramatically, making a lot of noise.

Components

  • RGB LED
  • Phototransistor
  • Buzzer
  • Push button
  • 1M Ohm resistor
  • 10K Ohm resistor

Learning Goals

  • Introducing the Arduino Cloud
  • Introducing the Arduino IoT Cloud Remote app
  • Managing sensors with the Arduino Cloud
  • Creating an Arduino Cloud Dashboard

Want to Know More?

This tutorial is part of a series of experiments that familiarise you with the Arduino MKR IoT Bundle. All experiments can be built using the components contained in the Arduino MKR IoT Bundle.

Circuit

In this project, we will be using the following circuit. In it, we have a 1M Ohm resistor connected between the ground and the A2 pin used for the phototransistor. And a 10k Ohm resistor connected between between ground and the push button.

Arduino IoT Bundle
Arduino IoT Bundle

Make sure to place the phototransistor in reverse polarity, meaning the long leg is connected to A2 and the short leg is connected to 3.3 V.

Setting up the Arduino Cloud

If you are new to the Arduino Cloud, check out our Getting Started Guide.

Template

To connect your board to the Arduino Cloud, we will use The Nerd Template. This template installs a specific sketch on your board and creates a dashboard that allows you to interact with your board: you don't need to write any code at all!

See the image below to understand how to set it up.

Thing overview
Thing overview

Creating a new thing and dashboard is easy. First, go to the Arduino Cloud site here. Setting up the Cloud consists of the following parts:

  • Creating a Thing
  • Attaching a Device
  • Adding Variables
  • Adding Network credentials

Arduino IoT Bundle

Variables

We will start by adding three variables:

  • nerdsFood
    -
    INT
    -
    READ ONLY

  • nerdsLight
    -
    INT
    -
    READ ONLY

Dashboard

The next step to deploying our project is adding a control panel using the Arduino IoT Dashboards. We can navigate to Dashboards > Build Dashboard > ADD, then we can add two widgets and link them to the variable as the following:

  • Gauge widget -> nerdsFood (max. 12)
  • Gauge widget -> nerdsLight (max. 500)

Arduino IoT Bundle

Setup Hardware & Sketch

Keeping track of the Nerd's food

To keep track of the Nerd's food we will be using an int variable. When the Nerd is in enough sunlight and the button is pressed it will be fed. Making a sound so you know that it received the food. The RGB LED will change color depending on the Nerd's hunger state.

1/* Set color status feedback */
2if(nerdsFood < 4){ /* if starving show red */
3 setColor(255, 0, 0); /* Red */
4}
5else if(nerdsFood >= 4 && nerdsFood < 8){
6 setColor(255, 255, 0); /* yellow */
7}
8else{
9 setColor(0, 255, 0); /* green */
10}

To keep track of time, we store a timestamp using

millis()
at a specific event, such as when the food supply is last decremented. Then, at regular intervals, we compare the current
millis()
value with this stored timestamp to determine if a certain amount of time has elapsed. For example, if we want to decrease the food supply every 10 minutes, we check if the difference between the current millis() value and the stored timestamp is greater than or equal to 600,000 milliseconds (10 minutes in milliseconds).

The max food storage is set to 12, this can be expanded by changing the threshold in the "if" operator, and don't forget to update the tracker on the dashboard as well so you can accurately track the food that the Nerd has.

1if (currentMillis - previousMillis >= interval) {
2 // save the last time you called onNerdsTimeChange
3 previousMillis = currentMillis;
4
5 // call the eating function
6 eating();
7 }
1void eating() {
2 if(nerdsFood > 0){
3 nerdsFood--;
4 delay(200);
5 }

The Nerd will start with 2 food the first time it wakes up, then this value will be tracked by the Cloud. If it dies it will start over with 2 food as well.

1if(nerdsFood == 0 && justWokeUp == false && !sosTriggered){
2 // DIE :(
3 SOS();
4 sosTriggered = true;
5 }

Checking the light level

To check so that our Nerd gets enough sunlight we will use a Phototransistor. Keeping track of the light level with the nerdsLight Cloud variable.

1int sensorPin = A2;
2nerdsLight = analogRead(sensorPin);

When the Nerd first wakes up, this is when the device is started and the Nerd first receives sunlight. It will make a sound and blink its light. Then the variable will be checked every time you try to give the Nerd some food. The threshold of the light level can be changed if you are having trouble feeding the Nerd. You can use the Cloud to check what values you get when the Nerd is in the light, and then change the threshold here in the code:

1if(nerdsFood < 12 && nerdsLight > 300)

Time tracker with the Arduino Cloud

The Nerd will get hungry every 10 minutes and eat the food it has been given. To keep track of when the Nerd gets hungry we will use a time variable from the Arduino Cloud. We will use the auto-generated functions we get from the Arduino Cloud to make the changes to the Nerd's food when it eats. This function will be executed after an amount of time has passed. The time is determined in the nerdsTime variable configuration. In this example we set the time to be 10 minutes, this has to be stated in seconds.

Want to Know More?

This tutorial is part of a series of experiments that familiarize you with the Arduino IoT Bundle. All experiments can be built using the components contained in the IoT Bundle.

Full Code

Note: For the code to work you also need

thingProperties.h
which is automatically generated when creating a Cloud sketch.

1#include "thingProperties.h"
2
3// RGB LED pins
4int redPin = 6;
5int greenPin = 8;
6int bluePin = 7;
7
8int buzzerPin = 9;
9int sensorPin = A2;
10int buttonPin = 2; // the number of the pushbutton pin
11
12bool justWokeUp = true;
13bool sosTriggered = false;
14int buttonState = 0;
15
16unsigned long previousMillis = 0;
17const long interval = 600000; // 10 minutes interval in milliseconds
18
19void setup() {
20 Serial.begin(9600);
21 delay(1500);
22 initProperties();
23 ArduinoCloud.begin(ArduinoIoTPreferredConnection);
24 setDebugMessageLevel(2);
25 ArduinoCloud.printDebugInfo();
26
27 pinMode(redPin, OUTPUT);
28 pinMode(greenPin, OUTPUT);
29 pinMode(bluePin, OUTPUT);
30 pinMode(buttonPin, INPUT);
31
32 nerdsFood = 5;
33}
34
35void loop() {
36 ArduinoCloud.update();
37
38 unsigned long currentMillis = millis();
39
40 nerdsLight = analogRead(sensorPin);
41 buttonState = digitalRead(buttonPin);
42
43 // Awaking notification
44 if(nerdsLight < 300 && justWokeUp){
45
46 //Print wake up message
47 Serial.println("woke up");
48
49 setColor(0, 255, 0); // green
50 tone(buzzerPin, 262, 1000); // tone(Pin, Note, Duration);
51 delay(2000);
52 setColor(0, 0, 0); // off
53 noTone(buzzerPin);
54 delay(1000);
55 justWokeUp = false;
56 }
57
58 if (buttonState == HIGH && !sosTriggered) {
59 if(nerdsFood < 12 && nerdsLight > 300){
60 nerdsFood++;
61 tone(buzzerPin, 40, 300); // tone(Pin, Note, Duration);
62 delay(100);
63 tone(buzzerPin, 40, 300); // tone(Pin, Note, Duration);
64 delay(100);
65 noTone(buzzerPin);
66 }
67 delay(100);
68 }
69
70 // Set color status feedback
71 if(nerdsFood < 4){ // if starving show red
72 setColor(255, 0, 0); // Red
73 }
74 else if(nerdsFood >= 4 && nerdsFood < 8){
75 setColor(255, 255, 0); // yellow
76 }
77 else{
78 setColor(0, 255, 0); // green
79 }
80
81 if (currentMillis - previousMillis >= interval) {
82 // save the last time you called onNerdsTimeChange
83 previousMillis = currentMillis;
84
85 // call the hungry function
86 eating();
87 }
88
89 if(nerdsFood == 0 && justWokeUp == false && !sosTriggered){
90 // DIE :(
91 SOS();
92 sosTriggered = true;
93 }
94
95}
96
97
98void SOS(){
99 for(int a = 0; a < 3; a++){
100 setColor(255, 0, 0); // Red
101 tone(buzzerPin, 262, 4); // tone(Pin, Note, Duration);
102 delay(100);
103 setColor(0, 0, 0); // off
104 noTone(buzzerPin);
105 delay(50);
106 }
107
108 delay(1000);
109 for(int a = 0; a < 3; a++){
110 setColor(255, 0, 0); // Red
111 tone(buzzerPin, 262, 2000); // tone(Pin, Note, Duration);
112 delay(1000);
113 }
114
115 for(int a = 0; a < 3; a++){
116 setColor(255, 0, 0); // Red
117 tone(buzzerPin, 262, 100); // tone(Pin, Note, Duration);
118 delay(100);
119 setColor(0, 0, 0); // off
120 noTone(buzzerPin);
121 delay(50);
122 }
123 delay(1000);
124}
125
126// Send RGB values to the LED pins
127void setColor(int red, int green, int blue){
128 analogWrite(redPin, red);
129 analogWrite(greenPin, green);
130 analogWrite(bluePin, blue);
131}
132
133void eating(){
134 if(nerdsFood > 0){
135 nerdsFood--;
136 delay(200);
137 }
138}

Suggest changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.