Saturday 25 June 2016

Making Boolean logic gates from transistors

Last week I hooked up a 7 segment display to the photon using a decade counter integrated circuit. While digging it out of my electronics box I found a bunch of logic gates I had too. They are the same style as the decade counter, looking like large bugs. This got me curious as to how you actually make a logic gate in hardware. As a software developer conditional logic is one of your day-to-day tools, but I've only learned about hardware gates back at University in a first year hardware module.

After a bit of googling I came across this article describing how to make various logic gates from transistors. So with a few components I had around I made AND, OR, NAND, NOR and NOT gates from scratch. I used the photon's tinker mode to turn on and off the inputs to test the gates. It was pretty simple once you get your head around what a transistor actually does but by the end I had a bit more respect for the modern chips that have billions of transistors in a single CPU.

What you will need

  • 2 NPN transistors (I used 2N3904)
  • 2 10kΩ resistors
  • 1 4.7kΩ resistor
  • 1 LED

A note on transistors

Transistors come in 2 flavours, NPN and PNP. 
2N3904 NPN transistor
  • NPN transistors do not let current flow through it unless the base input is charged. This means they are default off
  • PNP transistors let the current flow through it unless the base input is charged, when the flow is stopped. This means they are default on
I'm going to choose to use NPN transistors here as I want the behaviour of current only flowing when the inputs are HIGH. You could equally make logic gates using PNP transistors but you just have a different circuit configuration to achieve the same effect. If you want more information about why NPN/PNP transistors behave the way they do, check out this article which explains it in detail.




Making the logic gates

Each of the gates, except NOT, require 2 transistors; one for each input into the gate. We will connect the photon digital output pins D0 and D1 to a base input (the middle pin) of each transistor and this value will determine whether current flows across the transistor collector and emitter pins. We will then wire up the emitters and collectors in different configurations to create the different logic gates. A current will be provided across the transistors from pin D7 so keep that HIGH all the time.



Using the diagrams here as reference:


AND Gate


The finished AND gate:

AND Logic Gate

D0 and D1 are the 2 inputs into the AND gate. They are each fed into a 10kΩ resistor and then into the middle pin of the transistor. D7 is providing the current across the transistors which are arranged in series by connecting the emitter of one transistor to the collector of the other. The emitter of the second resistor is then fed into an LED then out to ground.

How it works

If a current is applied to the base (middle pin), the transistor lets current flow across it. When you have 2 connected in series you need both D0 and D1 to be HIGH in order to let the current flow all the way across both transistors to the LED. If either of the pins are LOW then the current cannot flow to the LED. This gives us the behaviour of an AND gate.



OR Gate


The finished OR gate:

OR Logic Gate

D0, D1 and D7 are used in the same way as the AND gate with the same 10kΩ resistors. The different here is that we connect the transistors to D7 in parallel rather than series. So we have a wire from D7 to each collector and then a wire from each emitter to the LED input. The transistors are entirely independent from each other.

How it works

Each transistor is independently connected to the LED. This means you only need to apply current to one of the D0 or D1 pins to cause current to flow to the LED. The LED will be lit in all input combinations except if both D0 and D1 are LOW. This gives us the behaviour of an OR gate.


NAND Gate


The finished NAND gate:

NAND Logic Gate
D0, D1 and D7 are used in the same way as the AND gate with the same 10kΩ resistors. The transistors are also still connected in series. The differences here are that the LED is connected before the transistors instead of afterwards, and there is now a 4.7kΩ resistor between D7 and the LED/first transistor collector. The emitter of the second transistor is now connected straight to ground instead of the LED.

How it works

If a current is applied to the base (middle pin), the transistor lets current flow across it. When you have 2 connected in series you need both D0 and D1 to be HIGH in order to let the current flow all the way across both transistors to ground. When the transistors allow the current to flow, this provides a short circuit to ground and so no current flows to the LED. The LED will be lit in all input combinations except if both D0 and D1 are HIGH. This gives us the behaviour of a NAND gate.



NOR Gate


The finished NOR gate:

NOR Logic Gate

This setup is a hybrid between the OR and NAND circuits. The transistor collectors are both connected to the 4.7kΩ resistor in parallel with their emitters both connected to ground. The LED is wired in above the transistors similar to the NAND gate.

How it works

As the transistors are independent of each other because they are connected in parallel (like the OR gate), you only need one of D0 or D1 to be HIGH to provide a short circuit to ground. This means the LED will only be lit when both D0 and D1 are LOW as this is the only configuration that allows current to flow through the LED. This gives us the behaviour of a NOR gate.



NOT Gate

This gate is a little simple than the rest as it only involves one transistor (because it only has one input). But it builds on what we learned from the NAND/NOR gates:

NOT Logic Gate

D0 is the input source, we are still using the 4.7kΩ resistor after the D7 power source and the LED is connected before the transistor similar to the NAND/NOR gates. The transistor emitter is connected to ground.

How it works

If current is applied to the base (middle pin), the transistor lets current flow across it. As we have seen before, this allows the current coming from D7 to short circuit to ground instead of flowing round to the LED. This means the LED is lit when D0 is LOW as this is when current can flow to the LED and pulling D0 HIGH will turn off the LED. This gives us the behaviour of a NOT gate.


Conclusion


This exercise had no purpose other than satisfying curiosity as to how you would make logic gates from transistors. It is one thing looking at the Boolean logic tables and accepting that if the inputs are X and Y then the output is Z, and another to see it yourself in practice and understand why it is behaving like that. 

I googled for how to make transistors but I'm not quite sure I want to go there...



Sunday 19 June 2016

Particle Photon: Driving a 7 segment display

This weekend I thought I'd try and hook up a 7 segment number display to my photon. I did this a few years back with an arduino but couldn't remember how, so it was a nice learning experience in wiring and reading data sheets very closely.


The Components


This is a 7 segment display:
A standard 7 segment display
This one has pins on the top/bottom

This one has pins at the top and bottom, but you can also get them with pins down the side. There are 7 pins to turn on each of the segments of the number, 2 ground pins and one for the decimal point to give a total of 10 pins.

Pin layout of the 7 segment display

You may think this is impossible to hook up to the photon as it needs 8 digital output pins but you can add an intermediate component to abstract control of the individual segments away from the photon so you only care about the digital number. This component is the 4026 decade counter. 

A 4026 decade counter IC

I put stickers on my ICs to tell them apart

This component takes in a clock signal, and for every cycle increments the output number and encodes it to 7 output pins that map to the a - g inputs of the 7 segment display. It can only count from 0 to 9 (hence the name decade counter) and it wraps back to 0 once 9 has been reached.

Here is a section of the 4026 datasheet:


You can see the output pins to drive the display and a couple of other pins I will explain in a minute.

The 4026 basically works like this:

      1. Reset the component by toggling pin 15 HIGH then LOW. This will send power to all 
          output pins except 7 (the cross bar) to form a zero on the display

      2. Toggle pin 1 LOW then HIGH. This will send power to the output pins required to produce
          a 'one' on the display (12 and 13)

      3. Toggle pin 1 again to produce a 'two'

      4. Repeat until you get to 'nine'

      5. Toggle once more and the display goes back to zero and additionally output HIGH on pin 5
          which can be hooked up to the clock pin of another 4026 decade counter to drive the 
         10's digit in a 2 digit number.


Where to get the components?


The best place I have found (from the UK) to get quite random components like this is bitsbox. Their stuff is pretty cheap and they seem to sell everything. I like to place an order for loads of random stuff (with plenty of duplicates in case I burn them out) and see what stuff I can make.

But if you've got to have a component now, now now, then maplin is probably the best place as you can just walk into a store and buy it, albeit at a premium price for the convenience.

I bought these components from bitsbox, the 7 segment display and 4026 decade counter.


How to hook it up


You need quite a few jumper leads to hook this up. 



Photon to decade counter

  • D6 to pin 15 (Vdd) - this provides power
  • D0 to pin 1 (clock) - this provides the clock signal
  • D5 to pin 3 (display enable in) - when this pin is HIGH it turns on the output pins. Without it you will get no signal sent to the display

Decade counter

  • Pin 2 (clock inhibit) to GND - when this pin is HIGH it inhibits the clock from advancing the number. We don't want this to happen so ensure it is always LOW
  • Pin 8 (Vss) to GND - standard ground output of the IC
  • Pin 15 (reset) to GND - when this is toggled it will reset the counter to zero. We don't want this to happen so just connect it to LOW to stop any interference
Lots of connections required for the decade counter

Decade counter to 7 segment display

  • Just match up the output pins to the input pins of the display. I.e. connect output 'a' to input 'a' etc.

Photon to 7 segment display

  • D7 to pin DP - only if you want the decimal point lit up

7 segment display

  • Connect the 2 cc pins to GND

Phew! Ok now we've got all that hooked up we just need the little photon program to toggle the clock signal to increment the number on the display and set pins D5, D6 and D7 HIGH.

The code


The program is pretty simple. We want to provide power to the counter, also activate the output pins on the counter, and finally start toggling the clock pin.


 int clockPin = D0;  
 int enableDisplay = D5;  
 int counterPower = D6;  
 int displayDecimalPoint = D7;  
   
 void setup() {  
   
   pinMode(clockPin, OUTPUT);  
     
   pinMode(enableDisplay, OUTPUT);  
   pinMode(counterPower, OUTPUT);  
   pinMode(displayDecimalPoint, OUTPUT);  
     
   digitalWrite(enableDisplay, HIGH);  
   digitalWrite(counterPower, HIGH);  
   digitalWrite(displayDecimalPoint, HIGH);  
 }  
   
 void loop() {  
     
   digitalWrite(clockPin, HIGH);  
   delay(500);  
   digitalWrite(clockPin, LOW);  
   delay(500);  
 }  

Once you flash this program onto your photon you should see the 7 segment display counting repeatedly from zero to nine.



Saturday 18 June 2016

Particle Photon: Making HTTP requests

One of the best features of the photon is the fact that it is wireless and can connect to the internet to integrate with other devices and services without requiring any extra components. Making HTTP requests from the photon is the most flexible way to send you data somewhere remote.

To make things as simple as possible, Particle have implemented a webhook system to reduce the amount of code you need to write to make an HTTP request. This is nice to have but it's actually not very hard to make requests straight from the photon, without requiring the extra hop into the Particle cloud.

There is a HTTP client available from the official libraries of the Particle Build IDE. You can also get the code from github if you want to write your code locally without using the cloud IDE. Using this library you can easily make requests.

Here is a (quite contrived) example of making a get, post, put and delete request every 10 seconds. I have a little scala web server running on 192.168.1.169:8080 listening for requests. You can find the scala code here.

 #include "application.h"  
 #include "HttpClient.h"  
   
 HttpClient http;  
 http_header_t headers[] = {  
    { "Content-Type", "application/json" },  
    { NULL, NULL }   
 };  
 http_request_t request;  
 http_response_t response;  
   
 void setup() {  
   
   Serial.begin(9600);  
   
   request.ip = IPAddress(192,168,1,169);  
   request.port = 8080;  
 }  
   
 void printResponse(http_response_t &response) {  
   Serial.println("HTTP Response: ");  
   Serial.println(response.status);  
   Serial.println(response.body);  
 }  
   
 void getRequest() {  
   
   request.path = "/photon/time";  
   request.body = "";  
   
   http.get(request, response, headers);  
   printResponse(response);  
 }  
   
 void putRequest() {  
   
   request.path = "/photon/measurements";  
   request.body = "{\"measurementType\":\"static\", \"value\": 1000}";  
   
   http.put(request, response, headers);  
   printResponse(response);  
 }  
   
 void postRequest() {  
   
   request.path = "/photon/measurements";  
   request.body = "{\"measurementType\":\"static\", \"value\": 2000}";  
   
   http.post(request, response, headers);  
   printResponse(response);  
 }  
   
 void deleteRequest() {  
   
   request.path = "/photon/measurements/123";  
   request.body = "";  
   
   http.del(request, response, headers);  
   printResponse(response);  
 }  
   
 void loop() {  
   
   getRequest();  
   postRequest();  
   putRequest();  
   deleteRequest();  
   
   delay(10000);  
 }  
   

If you connect the serial monitor you will see the responses come back:



Thursday 16 June 2016

Particle Photon: Serial communication

I have known for a while that you can send data from the Photon to your computer via the serial connection and view it using the particle serial monitor. But I only recently found out that you can send data from your computer to the Photon too. For some reason I associated 'serial' with 'one-way' but it's really just 'one bit at a time'.

For example here is a small program that will echo back the data you send from your computer to the Photon if you have the serial monitor open:


 void setup() {  
   
   Serial.begin(9600);  
 }  
   
 void loop() {  
     
   int availableBytes = Serial.available();  
     
   if (availableBytes > 0) {  
      
     char message[availableBytes];  
      
     for(int i = 0 ; i < availableBytes ; i++) {  
        
       message[i] = Serial.read();  
     }  
   
     Serial.println(message);  
   }  
     
   delay(1000);  
 }  

You cannot send data to the Photon using the serial monitor as it can only receive data but you can send data using the CLI instead. On Linux you can run:


 $> echo -e "hello world" > /dev/ttyACM0  


This will send the characters 'hello world' over the serial connection to the Photon who will then read in the characters and print them back to the serial monitor.

After reading a bit about serial connections I found out:

1. Data is sent one bit at a time so it is pretty slow but adequate for talking to the Photon

2. Serial communication comes in 3 flavours:

  • Simplex - data is only sent in one direction

  • Half-duplex - data can be sent in 2 directions, but only one direction at a time
  • Full-duplex - data can be sent in 2 directions simultaneously


3. USB is a form of serial communication. USB 3.0 is full-duplex but earlier versions are only half-duplex. Full duplex data transfer helps USB 3.0 achieve it's super fast transfer speeds as it has dedicated wires for each communication direction.

Sunday 12 June 2016

Multimeters: Measuring voltage, current and resistance

After accidentally blowing up lots of components and failing to understand why my multimeter wasn't giving me readings I expected, I decided to invest a bit of time trying to understand exactly what I was measuring and how to do it properly.

Multimeters


This is my multimeter. It's pretty standard with no flashy extra abilities. It can measure voltage, current and resistance (and a couple of other things that I won't go into). One interesting thing to note is the fact that it can measure both AC and DC voltage (DC on the left hand side, AC on the right). With hobby electronics it is likely you will only ever be measuring very small DC voltages and won't need to measure AC. The AC measurement ranges are also scarily high (200/600) so unless you are an expert and know what you are doing I don't recommend you attach your probes to anything mains powered as it is very dangerous.  
A multimeter

You can get various types of probes to stick into the connector ports, but I just have standard pokey stick type ones. The probes are exactly the same other than their colour. Plug the black one into the COM port and the red one into the right hand VΩmA port and you're ready to start measuring things. (The left hand port is for measuring AC voltages and high currents up to 10A).


Voltage


Voltage is measured across 2 points in a circuit and is the difference in electrical potential energy between those 2 points, where one point has a higher positive charge than the other.  (Check out this article for a more really good description of voltage).You measure voltage in parallel using the multimeter.

the multimeter is connected in parallel

If you have a 3.3V source (like the photon) and you place your multimeter probes on the source and GND then you should get a reading of 3.3V.

You can measure points within a circuit to perform nodal analysis and see the voltage drop across individual components. For example if we hook the photon up to two 330Ω resistors in series we can measure across each resistor to see the voltage drop equally across them both.

The voltage measured in parallel across both resistors is 3.37V

The voltage measured across just one resistor is 1.65V,
half of the total voltage of the circuit

Note: the multimeter is sampling the readings and taking an average so it is expected that they may differ a bit.


If we measure the current as well (4.93mA, see the next section) then we can validate these readings using Ohm's law:

V = IR
Voltage(V) = Current(A) x Resistance(Ω)


V = 0.00493A x (330Ω + 330Ω)
  V = 3.2538V 



Current


Current is a measurement of the number of electrons passing through the circuit per second. 1 amp is defined as 6.241*1018 electrons (1 Coloumb)/sec. Because you are measuring the flow of current you must connect your multimeter in series so the electrons flow through it.


the multimeter is connected in series


We measured the internal voltage across the photon with no components connected and got a reading of about 3.3V. We mustn't do this with current though as this would involve creating a circuit of so little resistance it may damage the photon.


don't measure current in a circuit with no resistance


Instead let's jump to measuring the current of a circuit with resistors. When we connect the multimeter in series with a circuit containing different numbers of resistors we can see the current changes. With one 330Ω resistor you get a current of 9.33mA and with two resistors you get 4.93mA.

The current measured in a circuit with one 330Ω resistor is 9.33mA

The current measured in a circuit with two 330Ω resistors is 4.92mA

What these measurements show us is that as the resistance in a circuit increases, the current decreases. This intuitively makes sense as if you put obstacles in the way of something flowing along, the movement will be slowed.


Again we can validate these readings using Ohm's law:

With two resistors:

V = IR
 I = V / R
 I = 3.3V / (330Ω + 330Ω)
 I = 0.005A
 I = 5mA


With one resistor:

V = IR
 I = V / R
 I = 3.3V / 330Ω
 I = 0.01A
 I = 10mA

Note: Again, the multimeter does not give us completely exact readings so it is expected that they are a little bit off from the calculated current value




Resistance


Resistance is a measurement of how much an object opposes the flow of electrons through it. To measure resistance with your multimeter, connect the probes across the object. The multimeter will then pass a small current through it to measure the resistance. Do not try to measure resistance in a powered circuit as the current will mess with the multimeter's readings.

Here we can verify that the 330Ω resistor does in fact provide that much resistance:

The resistance is measured as 337Ω



Sunday 5 June 2016

How to make a laser tripwire alarm

I have been trying to come up with a project for an upcoming session of my company's branch of CoderDojo. This is a voluntary educational group who host classes to teach children about programming and computer hardware. It's pretty tough to come up with a project that a group of children (aged between 6 - 16) can complete in 2 hours and remain interested. Last session we make an augmented reality game using a webcam and the Scratch programming environment. It was really cool and the kids seemed to have fun. However this time we would like to do a project involving hardware too. Another colleague is investigating the Makey Makey and I am trying to come up with something using micro controllers.

An idea I came up with was to get the kids to make booby-traps to either construct an obstacle course or to create a mission impossible style trapped room to protect an artifact. In theory this shouldn't be too tricky as the various sensors are pretty easy to hook up to an arduino/photon and the code to control them is very simple. The obvious trap to start with (to me anyway) is a laser tripwire. This is among the more complicated of the traps to set up, but the outcome will be sweet.

So I spent yesterday putting together a laser tripwire that raised an alarm when tripped to see how it would come together. It took a couple of hours due to me not having made one before, but I'm pretty confident we could get a kid to complete it in under an hour.


What you will need


3V laser module
piezo buzzer



photo resistor
10kΩ resistor

Wiring circuit

I set the circuit up on a breadboard, but you would probably want to solder some of the components together if you wanted to use the tripwire for real. This is just to show you how it all connects.


Photo resistor

We use a photo resistor to detect whether the laser is currently pointing at it or not. The more light that falls on the resistor, the lower the resistance becomes, so we can use this to detect whether the laser is currently pointing at it or not. When set up inside a voltage divider we can translate the variation in resistance to a variation in voltage. We can then measure that voltage to decide whether to sound the alarm or not. We measure V(out) from the voltage divider with the green wire hooked up to analog pin A1. We hook up the input voltage to digital pin D6 which we will pull HIGH at the start of the program to provide a nice steady 3V.


Buzzer

The piezo buzzer is hooked up to 2 digital pins on the photon. We will control the pins from the photon program when we have detected the laser is not pointing at the photo resistor (i.e. someone has broken the beam). A piezo buzzer makes a click sound when you apply a voltage. The faster you generate clicks (by flipping the input between LOW and HIGH) the higher the frequency of the sound produced. I am using the code from the bitsbox component listing to generate the tone.


The Laser

For simplicity I have used a laser module that includes a driver to keep the voltage steady to produce a regulated beam. This makes the component more expensive, but also much easier to use as you just need to hook it up to a 3V power source and voila, frickin' lasers! I obviously have to mention the fact that you shouldn't point this laser into your eyes or the eyes of anyone else. While the laser beam is not strong enough to disintegrate your enemies, it will damage your eyes if you look directly down the beam. So don't. Hook up the laser to pin D6 to power it up and point it at the photo resistor. 

Make sure the laser is pointing directly at the photo resistor

Photon Code

The code we need for the tripwire is very simple. We need to read the value from the voltage divider, compare it to a value to decide whether we think the laser has been tripped and then sound the buzzer. Here is the code:


 int sounder_A = D2;  
 int sounder_B = D4;  
 int tripwire_power = D6;  
 int tripwire_input = A1;  
   
 void setup() {  
   
   pinMode(sounder_A, OUTPUT);  
   pinMode(sounder_B, OUTPUT);  
     
   pinMode(tripwire_power, OUTPUT);  
   pinMode(tripwire_input, INPUT);  
     
   digitalWrite(tripwire_power, HIGH);  
     
   Serial.begin(9600);  
 }  
   
 void loop() {  
     
   int tripwire = analogRead(tripwire_input);  
   Serial.println(tripwire);  
     
   if(tripwire > 1000) {  
     beep(100, 4000);  
   }  
 }  
   
 void beep(long duration, int freq) {  
     
   duration *= 1000;  //convert the duration to microseconds  
   int period = (1.0 / freq) * 1000000; //get the oscillation period in microseconds  
   long elapsed_time = 0;  
   while (elapsed_time < duration) {  
     digitalWrite(sounder_A, HIGH); //Piezo ports go hi/lo then lo/hi  
     digitalWrite(sounder_B, LOW); //to generate the tone  
     delayMicroseconds(period / 2);  
     digitalWrite(sounder_A, LOW);  
     digitalWrite(sounder_B, HIGH);  
     delayMicroseconds(period / 2);  
     elapsed_time += (period);  
   }  
     digitalWrite(sounder_A, LOW); //kill the output  
     digitalWrite(sounder_B, LOW);  
 }  

Play around with the values to generate whatever sound you want from the buzzer. If you're feeling fancy you can get it to play a tune. Anecdotally I found that the tripwire value read around 150 when the laser was hitting the photo resistor and around 1800 when tripped so I chose a trigger value of 1000 to activate the buzzer.

Break the tripwire and trigger the alarm



You can see the measurements from the serial output here: