Moonbase Otago - Dunedin Arduino project - Inputs

Arduino (D1) Inputs

Making a pin a digital input

All the pins on the WeMOS D1, analog and digital pins can be used as digital inputs - all you need to do is use the "pinMode()" routine, usually in setup(), to configure the pin - for example to make digital pin D6 an input: pinMode(D6, INPUT);

Below we'll explain about "pullup resistors" - you can enable a built in pullup resistor on each input with this call:

	pinMode(D6, INPUT_PULLUP);

Voltage Dividers

When you connect two resistors together in a row (we say "in series") the voltage in the middle depends on the ratio of the two resisters. We call this a "voltage divider", below are some examples, remember 'GND' means "0 volts". when the resistors are the same the voltage is half - when the resistor ratio is 2:1 you get 1/3 or 2/3 the voltage - when they are 3:1 you get 1/4 or 3/4. The larger the resistor on the bottom the higher the voltage.

More generally the output voltage is top-voltage*bottom-resistor/(bottom-resistor+top-resistor)

Switches

A special case of a voltage divider is when there is no resistor - in this case we say the voltage is "pulled up" or "pulled down" and the voltage on the output is the same as the power supply it is connected to:

If you connect a pullup to +V and a switch to ground then when the switch is on the midpoint will be 0V and when it's off the midpoint will be +V. As mentioned above Ardinos have built in pullup resistors that can be enabled in software.

The above examples show 10V power supplies - it makes thinking aboput voltages easier, in the real world we don't want to use more than 3.3v for our D1 because we could damage it.

Suppose you hook up a switch and connect it to digital input D6 like this:

Digital inputs don't measure voltages directly , just "on" or "off", or "1" or "0". "On" or "1" is an input voltage close to 3.3V, "off" or "0" is a voltage near 0V. You should avoid applying voltages that are not near 0 or 3.3V to a digital input, you can damage your CPU.

You read the state of a digital input like digital pin D6 using: digitalRead(D6), it will return 0 when the button is pressed, and if you connect an LED to pin D3 - for example:

	void setup() {         
  		pinMode(D6, INPUT);     
  		pinMode(D3, OUTPUT);     
	}

	void loop() {
		int val = digitalRead(D6);
		if (val == LOW) {
			digitalWrite(D3, HIGH);
		} else {
			digitalWrite(D3, LOW);
		}
	}

Then you now have a switch for an LED - remember that when the switch is pressed the input is LOW and we must set the LED on when it's high.

WeMOS D1 inputs have built in pullup resistors, you don't really need the 10k resistor, if you use "pinMode(D6, INPUT_PULLUP);" to set up the input you can simply use the following circuit:

You can toggle the LED on and off every time you press the switch by remembering the previous state of the switch and the state of the LED.

	int last_switch = HIGH;
	int led_state = LOW;
	void setup() {         
  		pinMode(D6, INPUT);     
  		pinMode(D3, OUTPUT);     
		digitalWrite(D3, LOW);
	}

	void loop() {
		int val = digitalRead(D6);
		if (val == LOW && last_switch == HIGH) {	// a button was just pressed
			if (led_state == LOW) {			// change the LED state
				led_state = HIGH;		// 	to what it isn't
			} else {
				led_state = LOW;
			}
			digitalWrite(D3, led_state);		// set the LED
		}
		last_switch = val;				// remember the last switch value
	}

Finally this simple code fragment will stop you program until a button is pressed:

	while (digitalRead(D6) != 0)yield();

Analog inputs

Only some pins can be analog inputs - the WeMOS D1 has just one 'A0' - it can be used to measure a voltage they return a value between 0 and 1023 every time they are read - analogRead(A0) returns the current voltage on pin 3 - these units are 1/1024ths of the voltage between 0V and 1V (not 3.3V, any value above 1V will read as 1023) (do about 0.001v per unit)

Measuring temperature

Many sensors that read more than on or off work by creating a voltage divider with one resistor replaced by a sensor which acts like a resistor - you pick a matching resistor that has a value that creates a voltage divider that makes a voltage below the 1V limit of what the WeMOS D1's analog input can measure - a 10k (10,000 ohms brown-black-orange or brown-black-black-red) works well for the part in the kit.

A "thermistor" is a device who's resistance changes as its temperature changes - you can put it in a circuit like this:

And read it with "analogRead(A0)" [for pin A0] - but what do the values mean? it depends on the device, we don't have data sheets for our thermistors but we can measure them. Here's a simple program, that reads A0 and prints out its value every second:

	void setup() {         
		Serial.begin(9600);
  		pinMode(A0, INPUT);     
	}

	void loop() {
		Serial.println(analogRead(A0));
		delay(1000);
	}

You don't need to type up this program there's an example program in File->Examples->01.Basics->AnalogReadSerial that already does this

To see this output open the serial monitor using Tools->Serial Monitor in the Arduino build system. You may need to change the baud rate in the menu at the bottom right of the screen to match the Serial.begin() in your program. Try holding the bulb of the thermistor with your fingers to warm it up and see the values change

With a thermometer you can build a table of temperatures and measured value to calibrate your thermistor.

This program turns on an LED when the temperature gets too high:

	void setup() {         
  		pinMode(D6, OUTPUT);     
	}

	void loop() {
		int v = analogRead(A0);
		if (v < 220) {
			digitalWrite(D6, HIGH);		// set the LED if the temp is too high
		} else {
			digitalWrite(D6, LOW);		// off the LED if the temp is low
		}
	}

Detecting light

Also in the kit is a Cadmium Sulphide (CdS) light sensor, you can use it in a voltage divider with a 10k resistor:

Try the program that prints out analog values above, shading the sensor with your hand should change the values printed.

Can you make a program that turns on an LED when it gets dark? what happens if you point the sensor at the LED?