[0:00] In this video we will look at 7 simple projects  that can be built using Arduino boards.   [0:07] Most of them will be based on Arduino Uno:  I chose it because its most popular and has   [0:12] enough input and output pins for most tasks.  Basically, everything we are going to be   [0:18] working on today can be implemented using  any Arduino board: as you probably know,   [0:24] the Arduino IDE automatically compiles your sketch  based on the board type you have chosen – which,   [0:30] I would say, is its huge advantage. As you  can see, I have the board type set to Uno. [0:38] We will also be using this cute project board  which I have purchased online – the link to order   [0:44] it you may find in the description. It fits  both Uno and Mega and features the so-called   [0:51] bread-board, which is a compact rig, that allows  one to build circuit prototypes without using a   [0:57] soldering iron. Bread-board's holes are  connected vertically – in this fashion,   [1:04] also the board contains dedicated holes for ground  and positive power rails, which, I should note,   [1:10] comes quite handy when assembling circuits... The  project board should be attached to Arduino this   [1:17] way: basically it's hard to mess anything up here,  but you should be carefull not to bend the pins,   [1:22] and watch your fingers when you do it. Also note  that the USB cable should not be unreasonably   [1:28] long. I've come across boards that were  not stable with cables longer than 1.5m –   [1:35] not necessarily that happens to you, but just  in case, keep it in mind, please. The USB   [1:42] cable will also be used to power the extension  shields – that's also important to remember. [1:48] To make sure everything's working, let us first  upload a test sketch that flashes the LED.   [1:54] The diode is wired to digital pin 7 and positive  power rail in series with a 430 Ohms resistor.   [2:02] I used the +5v rail here for no particular reason,   [2:05] it was easier to wire, but it doesn't really  matter, since Arduino Uno has push-pull outputs,   [2:11] and you can just as well use ground to power your  load. This, however, will affect output polarity.   [2:19] The recommended output current for ATMEGA328  is 20 mA, max current is 40 mA. Wiring several   [2:28] digital pins in parallel and switching them  simultaneously will provide higher output current.   [2:34] You have to remember though, that max total  current for all pins must not exceed 200 mA. [2:42] The first project we are going to  work on today is the Water detector.   [2:48] Such devices rely on the electrical conductivity  of water to warn the user of flooding.   [2:54] We will use a piece of standard PCB to produce  a sensor consisting of two isolated plates.   [3:01] Then, using a resistor in series, we will  feed 5v to them relative to the ground.   [3:08] Initially our sensor will output 5v. As it will be  immersed in water, a circuit will be established   [3:15] between the plates. Current will flow and the  voltage on sensor's positive plate will decrease.   [3:22] This, accordingly, will be reflected by  the value read by Arduino's A/D converter,   [3:28] and our program, once a certain threshold  value is hit, will sound the buzzer. [3:34] Before we proceed to writing the sketch, we  need to decide on the value of the R1 resistor.   [3:41] Let's set up an experiment...   [3:49] And the resistance of water turns out  to be around 5k. For the sensor to be   [3:55] triggered reliably, the resistor's value must  be proportionally large. I suggest we use 100k.   [4:03] Basically, the only purpose of this resistor  is to protect Arduino's A/D input from noise   [4:10] when the sensor is dry. If you experience  false positives, R1's value may be reduced.   [4:17] Note, that both pins of the beeper will be  connected to digital outputs of Arduino,   [4:22] and we will not use a ground connection here. This  will allow us to use push-pull outputs of ATMEGA   [4:29] in opposite phase to create a bridge circuit,  which will make the beeper sound louder...   [4:35] Ok, here's what our sketch will look like.  In the setup() section we program the LED   [4:41] and speaker pins for output, and initialize them.  In the main loop we use the analogRead() command   [4:47] to read the value of the A/D converter and sound  the buzzer if the value is greater than 700. The   [4:55] alarm() function plays tones and takes frequency  and duration as parameters... Let's check it out!   [5:04] As the sensor is flooded,  alarm immediately sounds.   [5:09] Because flooding is an emergency, the alarm  can only be disabled by resetting the device.   [5:20] And... the alarm goes off again, because  the sensor is still immersed in water. [5:27] The maximum value Arduino's A/D converter  can read is 1023. The greater the value,   [5:34] the higher the degree of flooding. If necessary,  you can change the alarm threshold by changing the   [5:40] value of this constant... Also, if we position the  sensor vertically and play with resistor's value,   [5:47] we can come up with water level sensor: its  resistance will reflect the degree of immersion.   [5:54] Note however, that electrical conductivity  of particular liquid will also affect the   [5:59] readings, so this method of level  measuring is not very accurate. [6:06] Our next device is the single LED automatic  night light. Its functionality is very simple.   [6:14] In low light conditions the LED lights up, and  when external lighting is detected, it turns off.   [6:22] Here you can see the schematic  diagram of this device.   [6:27] When I said “the single LED”, I literally meant  there isn't anything here except for the MCU and   [6:34] the LED. That's right! We are going to use the  same component both as a light emitter and as   [6:43] a light sensor, because LEDs can also sense light.  As you have probably guessed, the software part of   [6:50] this project will be a bit more complicated than  the hardware. But it is precisely this why we use   [6:57] microcontrollers! The problem is, the LED cannot  work both as an emitter and sensor simultaneously.   [7:05] But! Because LEDs switch really quickly, what we  can do is turn it off for a small amount of time,   [7:13] read the illuminance value, and then, based  on the result, switch the diode on or off.   [7:20] Here's the sketch source code. The LED is wired  to analog pin 2 using a 430 Ohms resistor.   [7:28] But how are we going to power the LED  with the analog input – you may ask?   [7:33] Actually, all analog inputs of  Arduino can act as digital outputs   [7:39] if you use the appropriate pinMode command.  ATMEGA328 is such a wonderful processsor! [7:45] And there's something else. Arduino's A/D  converter needs some time to perform its readings.   [7:52] This becomes even more evident if you keep  switching the pin from input to output mode.   [7:58] So, to make our program more stable, we need to  add a small delay before the analogRead() command,   [8:05] its less than 100 ms, but unfortunately,  will be noticable to the human eye.   [8:11] Also, while debugging the device  I came across another problem.   [8:16] After switching from digital to analog mode,  A/D converter's threshold is temporarily offset.   [8:23] This is probably caused by some transient  processes going on inside the ATMEGA chip. Anyway,   [8:28] we do not have time to wait for the offset to  be restored, so I introduced a new variable I   [8:35] called “shelf” that takes care of this error.  The main threshold constant, which equals 220,   [8:41] was found by trial and error method... If you  intend to build an LED night light of your own,   [8:48] you will probably have to play with this  value too, as it will differ from LED to LED. [8:53] Here's the source code of the program. At the  beginning of the loop we set the LED pin to   [8:58] logic zero and then switch it to analog mode. Then  we read the ADC value. The readData() functions   [9:05] performs 10 consecutive reads at 10 ms intervals.  This is a standard programmatic way of ruling out   [9:12] ADC errors and bounce. When we're done with the  ADC, we switch the LED pin to digital output mode.   [9:20] If the value read is greater than 220, we  turn the LED off. Otherwise, we turn it on.   [9:29] If the LED was turned on, we set the shelf  value to 180. If it was not, we set it to 0.   [9:37] Then there's a 2 seconds delay,  and then we start over again. [9:42] Let's check it out! Ok,   [9:54] if said that the flicker is unnoticable, I would  have probably lied. But in a real device it is   [10:01] not necessary to read the illuminance value so  frequently. Doing this once every 15 or even 30   [10:08] minutes will quite suffice. The Sun doesn't set  so fast, unless it's a total eclipse, of course.   [10:15] In that case I don't think anyone  will pay attention to flicker.   [10:19] To adjust this interval you need to  change the value of this constant. [10:27] Our next project is the touch sensor doorbell.  Here is the schematic diagram. We will use a   [10:34] regular metal paper clip as a finger sensor, which  we are going to wire to analog pin 0 of Arduino.   [10:41] We will also need a 1M resistor that we  will wire between this pin and ground.   [10:47] This device relies on the effect of  flow of capacitive currents from the   [10:52] phase wire located somewhere in  the room through the human body. [10:56] When you touch the paper clip, the MCU registers  signal on ADC input and performs the required   [11:03] action -- sounds a bell in our case. It should  be noted, that any such circuit is prone to   [11:09] interference and noise. To protect from them  usually a filter or a specialized IC is used.   [11:17] But we have a microcontroller here,  so we can do it all programmatically.   [11:22] For the device to work properly, we need it  to be triggered only by a 50 (or 60 depending   [11:27] on your country) Hz sine. Any other signals,  especially high frequency must be filtered out.   [11:36] To implement this, I wrote a simple frequency  meter here. In programming measuring frequency is   [11:43] usually done by counting the number of transitions  through zero during a set time interval.   [11:48] In our case it will be 25 ms – I picked it based  on the desired response time. If the number of   [11:56] pulses counted lies in the range of 70 to 150 –  I found these values empirically – then we have   [12:03] good signal... For now let us output the result  returned by our frequency detector onto the LED.   [12:13] As we can see, the program is quite stable and  is able to detect finger touches without errors.   [12:19] If the touch is too short, it's ignored. [12:23] Now let's try to playback some sound. Of  course, we can use simple square wave tones   [12:29] to buzz a primitive melody through the speaker.  But my intention was to get this thing to sound   [12:35] like a real old-school door-bell. I was able to  find online a WAV file with the required sound   [12:41] sample without trouble, here's what it sounds  like... The problem is, Arduino does not have   [12:48] a built-in D/A converter and it appears there's  no way we could play back sampled sounds with it.   [12:56] But! I found a quite remarkable library. It's  called damellis-PCM. According to the description,   [13:04] it can play back 8-bit PCM format samples  using the built-in ATMEGA's 328 timer.   [13:12] You need to download the library – the link is  in the descripiton – then unpack it and put the   [13:18] files into the “libraries” folder of Arduino  using the name PCM. You also need to open the   [13:24] PCM.c file and change the sample rate from 8000 to  11025 Hz – that's the format our WAV's gonna use.   [13:34] The sample file I got off the net has format  44 Khz 16 bit stereo. We must convert it to   [13:42] 11025 Hz 8 bit mono – note it's the only  format this library can actually play back.   [13:53] Conversion is necessary because Arduino's memory  is too small to store large chunks of data.   [13:59] Naturally, lowering the bit-resolution and  sample-rate will cause loss of quality, but in our   [14:05] case its not important. Now that we're done with  the conversion, let us delete the meta-headers   [14:11] from the WAV file and extract the raw 8-bit audio.  Now we need to put this data into a byte array.   [14:19] Unfortunately, the Arduino IDE can not  load a binary file into a variable.   [14:25] So, we need to convert our binary dump into  a standard C-style array definition operator.   [14:31] To do it, we are going to use  a program called Hex Workshop.   [14:39] Here's what our bell sample looks like now.   [14:42] Let's save it into a separate file  and include in our main program.   [14:49] To play back the sample all we need to do  is invoke the StartPlayBack() procedure.   [14:55] Its only two parameters are name  of the array and array's size.   [15:01] Please note, that you must wire the speaker  to digital output 11 of Arduino and this pin   [15:06] assignment may not be changed. This is due  to the fact that internal timer's output is   [15:12] hard wired to this pin inside the MCU.  Now let's hear it... Sounds good to me! [15:25] Our next project is the electronic ruler  that uses a salvaged CD-ROM spindle motor   [15:31] as displacement sensor. It's not secret to anyone  that any commutator DC motor is also a generator.   [15:40] However, the type of current such motor  will produce is not exactly direct,   [15:45] because the windings are constantly switched  by the commutator, thanks to which the circuit   [15:52] is periodically broken at a frequency  proportional to shaft rotation speed.   [15:57] This is the feature that our device will rely on.  You can see the schematic diagram on the screen. [16:04] We will also use a two-digit 7-segment  display operating in dynamic mode. Just   [16:11] like in our previous sketches, data will be read  with the analog input, but with a little nuance.   [16:18] It would be nice to implement counting in both  directions – up and down – the way it happens   [16:23] in a digital caliper, for example. We know,  that change of rotation direction will cause   [16:29] change of EMF polarity on motor's output.  How can we read this with the help of ADC?   [16:35] We can use a resistor divider and shift  ground level to half the power supply voltage.   [16:41] In this case motor's positive EMF will increase  the voltage, while negative one will decrease it.   [16:48] But we would like our circuit to stay as  simple as possible. So what are we gonna do?   [16:55] We will wire the motor between two analog  inputs – and no resistors! As we already know,   [17:02] ADC ins of Arduino can turn into digital outs.  So what we're going to do is switch one analog   [17:10] in to digital mode and set it to logic zero  while we read the ADC value of the other one.   [17:16] Then we just switch them. This will  effectively flip the input polarity of   [17:22] the ADC. I should also note that solutions like  this are often used in embedded programming. MCU   [17:23] pins are switched into different modes and sensors  are read one by one. Naturally, for this to work,   [17:23] switching must happen much faster than  change of data you are trying to analyze. [17:23] The main loop of the sketch is before us. The  “minus” button is used to reset the counter.   [17:30] We switch the A1 input into digital mode and  set it to zero. Then we read data from input A0.   [17:37] If the value is greater than 0, we increment the  distance counter. In the next section inputs A0   [17:45] and A1 are switched: A0 is now zeroed and A1 is  read data from. Based on the result, the distance   [17:54] counter is decremented. While experimenting I  found that faster motor rotation yields greater   [18:02] signal amplitude, which also affects the readings.  To rule out this error I introduced a calibration   [18:08] factor, found empirically. The accuracy of the  measurement can be adjusted using this constant. [18:16] Let's check it out...   [18:22] Good! If you have an old CD-ROM sitting somewhere  on the shelf, I think this project is for you! [18:29] The next circuit we are going to look at  today is the infrared remote control decoder.   [18:37] Using this device, you can switch  on and off any type of load.   [18:42] The circuit relies on the TSOP 1736 IR receiver.   [18:47] This element is not your regular photo-diode  or photo-resistor. It's an IC that outputs   [18:55] quality square wave signal, with noise and bounce  eliminated, which can be directly fed to the CPU. [19:02] In our case the IR-receiver is wired to line A2  – we don't really need the ADC converter in this   [19:09] sketch, but we can still use all analog pins as  digital inputs, if necessary. For the receiver IC   [19:20] to work, it also needs to be powered. LEDs are  connected to digital pins 2, 5, 7, 10 and 13.   [19:24] Hypothetically, if you want to control a  single load, like turn the lights on and off,   [19:30] you can get away with a simple D-type flip flop  instead of a CPU. However, such circuit will   [19:37] be very unstable, because it will react  to any infrared remote used in the room.   [19:43] Like when you wanna switch channels on your  TV, anytime you press buttons on the remote,   [19:48] your device will also be triggered. It may even  react to regular lights, because any electric   [19:54] bulb emits light in the infrared spectrum.  So, to make our device react to certain   [20:01] button-presses on a certain remote control,  we need to write the signal decoder program.   [20:08] Fortunately, Arduino already carries a  dedicated library that takes care of that.   [20:14] To compile this sketch you need to add the library  called “IR Remote” in your IDE. To use the library   [20:21] all you have to do is initialize it in your  setup() procedure, and then in your loop()   [20:27] procedure compare decoded keycodes to a list of  predefined code values. I have already run this   [20:34] sketch in debug mode, read the keycodes of this  cute tiny remote and put them into the program.   [20:40] As we can see, now pressing buttons on the  remote turns on and off the corresponding LEDs. [20:49] The last device we are going to build today is  the PC Gamepad controller. This project relies   [20:59] on Arduino's ability to emulate USB slave devices.  If properly programmed, it can act as a joystick,   [21:07] mouse, touchscreen, webcam, microphone, etc. To  use this function, all you have to do is attach   [21:16] your Arduino to your PC using the regular USB  connection. Please note, that only 32U4 based   [21:24] Arduino boards can emulate USB port. I will be  using Arduino Pro Micro here. Our keyboard will   [21:31] contain 4 cursor keys and a fire button. This  matches controller setup of most retro-games.   [21:38] If you wish, you can add more buttons to the  controller by adding their support in the sketch. [21:45] Here is the schematic of the device.  Buttons are wired to the ground,   [21:49] so we will use the INPUT_PULLUP  mode to read their state.   [21:53] To emulate USB keyboard we will use a  built-in Arduino library called “Keyboard”.   [21:59] For the sketch to compile successfully you must  activate it using the IDE menu... like this.   [22:08] To use the library all you have to do  is initialize it in the setup section.   [22:14] Then, as a keypress is detected on the gamepad,   [22:17] call the corresponding library routine to  send the key code to the USB interface. [22:23] At first glance, the algorithm is plain simple.  Read the buttons, send codes to the USB port.   [22:31] In reality, it's a bit more complicated.  When you control a player character,   [22:37] you often have to hold a button down or  press several buttons simultaneously.   [22:43] For example, for them to be running, you  have to press and hold the arrow key.   [22:48] For them to jump to the left, you must press  the “up” and “left” keys simultaneously.   [22:54] To implement this correctly, the process of  pressing a button must be split in two events:   [23:00] button press and button release. The events  must be sent to the USB interface separately.   [23:07] Fortunately, the Keyboard library supports this. [23:11] Now, how do we differentiate between a button  press and a button release on our gamepad? There's   [23:19] an old programmer's trick that accomplishes it.  We will define two sets of variables – according   [23:25] to the number of keys. There are 5 keys on our  gamepad, so we are going to need 10 variables.   [23:32] At the beginning of the loop we read all button  states and save them into this set of variables.   [23:39] At the end of the loop we copy these  states to the second set of variables.   [23:45] So, at the beginning of a new loop iteration all  R variables will contain the current button state,   [23:51] while the M varialbles will have the pre-stored  buttoon state from the previous loop iteration.   [23:58] Now all we have to do is compare these two arrays.  If the previous state of a button was RELEASED and   [24:06] current state is PRESSED -- note that PRESSED  is 0 -- it means we have the keypress event. So   [24:13] we send it to the USB interface. If the previous  state was PRESSED and current state is RELEASED,   [24:19] it means the user released the button. Send that  to USB too. If the current and previous states are   [24:27] the same, it means no event had happened, and  we don't need to send anything to the USB bus. [24:34] While debugging the program I also added  a small function called multiRead().   [24:39] It performs 50 consecutive reads of  the button and counts ones and zeros.   [24:44] Based on that it decides whether the button  is pressed or released. This is necessary   [24:50] to eliminate switching bounce and is called  debouncing in programming. On any event the   [24:57] LED will flash, and then a delay of 100 ms will  be executed – also to prevent bounce. Here we   [25:06] have keycodes to be sent to USB interface. Space  button will act as Fire key, its hex code is 20. [25:15] Shall we check it out? Looks  like everything's working!.. [25:30] And... that would be it for today! If you like  this video please show your support by subscribing   [25:37] to this channel and sharing it on social media.  Also don't forget to give me a thumbs up and write   [25:44] a comment. And if you'd like to drop me some  Bitcoin or Ether, please use wallet numbers,   [25:50] that you can find in the description  section. This was Ron Mattino! See you soon!