Analog Joystick

Connect an analog joystick to an Arduino. Read two analog values (x- and y-position) and a switch using a method witch does not hog the processor during the whole ADConversion.

The capacitor reduces digital noise on the analog readings.
Joystick

Code

static const byte ADC_CHANNEL_JOYSTICK_X = 0;
static const byte ADC_CHANNEL_JOYSTICK_Y = 1;

static const byte ADC_CHANNEL_MAX = 2;

byte adc_channel = 0;
bool joystick_button = 0; // 1 or 0
uint16_t joystick_x = 0; // 0~1023
uint16_t joystick_y = 0; // 0~1023


void setup() {
 Serial.begin(115200); // Remove
 
 pinMode(A0, INPUT); // Analog pin A0
 pinMode(A1, INPUT); // Analog pin A1
 pinMode(2, INPUT_PULLUP); // Digital pin 2
 
 // Setup adc
 ADCSRA |= 1 << ADEN; // Enable ADC, with no interrupt!
 ADCSRA |= ((1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0)); // Main clock / 128
 ADMUX = adc_channel; // Channel
 ADMUX |= 1 << REFS0; // Aref pin -> 100nF -> gnd
 ADCSRA |= 1 << ADSC; // Start first conversion
}


void loop() {
 byte changed = 0;
 
 // Analog
 if ((ADCSRA & (1 << ADSC)) == 0) { // ADC done
 changed += read_analog();
 }

 // Digital
 changed += read_digital();

 // Tmp
 if(changed > 0) {
 Serial.print("x: ");
 Serial.println(joystick_x);
 Serial.print("y: ");
 Serial.println(joystick_y);
 Serial.print("button: ");
 Serial.println(joystick_button);
 Serial.println();
 }
 delay(100); // Remove
}


byte read_digital() {
 byte state = 0;
 byte val = !(bool)(PIND & 0b00000100); // PORT IN D, pin nr 2
 if(val != joystick_button) {
 state = 1;
 joystick_button = val;
 }
 return state;
}


byte read_analog()
{
 byte state = 0;
 uint16_t val = ADC; // ADC is the full 10-bit, two-register, value from the last ADConversion
 
 switch(adc_channel) {
 case ADC_CHANNEL_JOYSTICK_X:
 if(joystick_x != val) {
 state = 1;
 joystick_x = val;
 }
 break;
 case ADC_CHANNEL_JOYSTICK_Y:
 if(joystick_y != val) {
 state = 1;
 joystick_y = val;
 }
 break;
 }

 adc_channel++;
 if(adc_channel >= ADC_CHANNEL_MAX) adc_channel = 0;
 ADMUX = adc_channel; // Channel
 ADMUX |= 1 << REFS0; // Aref pin -> 100nF -> gnd
 ADCSRA |= 1 << ADSC; // Start next conversion
 
 return state;
}


MAX7219 LED driver and 12088 8×8 LED matrix

The 8×8 LED matrix is 64 LEDs arranged in an 8 row, 8 column matrix, just like a chess board.

The Max7219 is used to control 64 LEDs at once. The Arduino sends data to the 7219 using the SPI serial communication protocol. You can have multiple SPI devices connected to an Arduino simultaneously.

For your convenience, the Arduino uses a library to talk to the LED driver. The library takes care of the SPI communication and may also have methods for writing characters or scrolling images. There are a number of Arduino libraries for MAX7219. I happened to chose LedControl.

Download the latest version of LedControl here (I used v1.0.1): https://github.com/wayoda/LedControl/releases

In-depth about the LedControl library, and a bit about the hardware. You don’t have to read it to follow the instructions in this article, but I scavenged a lot of info here: http://playground.arduino.cc/Main/LedControl

The hard part is to figure out the pin configuration of the 12088A/B LED matrix, and how to connect it to the 7219. So here are some images to help you out.

MAX7219 and 12088 LED-matrix

 

MAX7219->LED8x8_12088_02

 

#include "LedControl.h"

/****
   pin 12 is connected to the MAX7219 pin 1
   pin 11 is connected to the CLK pin 13
   pin 10 is connected to LOAD pin 12
   1 as we are only using 1 MAX7219
*/

LedControl lc = LedControl(12,11,10,1);
 
void setup() {
  // The zero is the MAX7219 id number, use 0 if there's only one chip
  lc.shutdown(0, false);  // Turn off power saving, enable display
  lc.setIntensity(0, 10); // Set brightness (0~15)
  lc.clearDisplay(0);     // Clear screen

  //lc.setLed(0,1,1,true); // turns on LED at col, row
  Serial.begin(9600);
  pinMode(2, INPUT);
}


void loop() {
  for (int row=0; row<8; row++) {
    for (int col=0; col<8; col++) {
      lc.setLed(0,col,row,true); // turns on LED at col, row
      delay(5);
    }
  }
 
  for (int row=0; row<8; row++) {
    for (int col=0; col<8; col++) {
      lc.setLed(0,col,row,false); // turns off LED at col, row
      delay(5);
    }
  }
}

IMG_7156_8x8_LED_matrix_01

Light sensor, LDR

The light sensor is also called a light-dependent resistor (LDR) or photocell. It is connected to Arduino pin A0. analogRead measures the voltage at the pin. You will get a value between 0 and 1023 (where 0 equals ground and 1023 equals +5 volts).

Changing the type of lamps and ambient light will give a bit of variation in your readings. In many cases a covered sensor equals about 500 and an exposed sensor is around 800. So under those circumstances an ON / OFF threshold-value of about 700 would be fine.

 

 

Light sensor


 

 

Code

void setup() {
  Serial.begin(9600); // Set up serial communication with the computer
}
 
void loop() {
  int lightSensorValue = analogRead(A0);     // Read the input on analog pin 0
  if(lightSensorValue > 700) {
      Serial.println("Light switch is ON");  // Sensor is receiving light
  } else {
      Serial.println("Light switch is OFF"); // Sensor is covered
  }
  delay(1);                          // Don't do analogRead too often
}

Read a pot, control 5 LEDs

The pot controls which LED is turned on. The pot is connected to Arduino pin A0. analogRead is used to measure the voltage at A0.

You will get a value between 0 and 1023 (where 0 equals ground and 1023 equals +5 volts).  The analog range is divided into 5 sections (1023 / 5).

Five LEDs are connected to the digital pins 2, 3, 4, 7 and 8. Use a switch statement to address individual pins depending on pot rotation.

Use a small delay to let the circuitry rest before doing the subsequent read, or the value can be erroneous.

Connect a Potentiometer

 

5 LEDs to individual pins

Code

void setup() {
  Serial.begin(9600); // Set up serial communication with the computer
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
}
 
void loop() {
  int analogValue = analogRead(A0);  // Read the input on analog pin 0
  int pinSelect = analogValue / 204;
  Serial.println(pinSelect);         // Print value to serial monitor
  delay(1);                          // Don't do analogRead too often
  
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(7, HIGH);
  digitalWrite(8, HIGH);
  
  switch(pinSelect) {
    case 0:
      digitalWrite(2, LOW);
      break;
    case 1:
      digitalWrite(3, LOW);
      break;
    case 2:
      digitalWrite(4, LOW);
      break;
    case 3:
      digitalWrite(7, LOW);
      break;
    case 4:
      digitalWrite(8, LOW);
      break;
    
  }
}

Read a pot, print to Serial Monitor

The USB connection is used for serial communication between Arduino and computer.

The potentiometer pin 2 is connected to Arduino pin A0. analogRead is then used to measure the voltage at the pin. (The potentiometer rating doesn’t matter, but avoid lower resistances than 5k, so you don’t get an uneconomically high current flow.) You will get a value between 0 and 1023 (where 0 equals ground and 1023 equals +5 volts).

Use a small delay to let the circuitry rest before doing the subsequent read, or the value can be erroneous.

Code

void setup() {
  Serial.begin(9600); // Set up serial communication with the computer
}
 
void loop() {
  int analogValue = analogRead(A0);  // Read the input on analog pin 0
  Serial.println(analogValue);       // Print value to serial monitor
  delay(1);                          // Don't do analogRead too often
}

12 volt Solenoid or Motor

Use a 12 volt solenoid or motor. Connect a 12 volt power adapter to the Arduino board. On the board there is a pin called Vin that will provide the 12 volts directly from the power adapter. Use Vin to power the solenoid / motor.

There will be a lot of current flowing through the solenoid. If the flow keeps on too long, the solenoid will get very hot. The on-time will probably needs to be shorter than a second.

The term duty cycle means the relation between on-time and off-time. Generally the duty cycle has to be less than 50% if the solenoid shall be turned on and off repeatedly.

Solenoid

IMG_7142_solenoid_01

Code

int ledPin = 13;

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

void loop() {
  digitalWrite(ledPin, HIGH);
  delay(50); // Solenoid gets hot if pin is HIGH too long
  digitalWrite(ledPin, LOW);
  delay(1000);
}

 

Blink LED

Limit the current flow through the LED with a small resistor R1, ca 200~1000Ω. Otherwise the LED will burn.

The LED can be connected in a few ways.
• Either the Arduino pin (pin 13 in this case) SOURCES 5v to the LED: the LED’s + pin is connected to the Arduino pin. The LED’s – pin is connected to GND.
• Or the Arduino pin SINKS the circuit through the LED. The LED’s + pin is connected to +5 volt supply. The LED’s – pin is connected to Arduino pin 13.

Code

int ledPin = 13;

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

void loop() {
  digitalWrite(ledPin, HIGH);
  delay(1000);
  digitalWrite(ledPin, LOW);
  delay(1000);
}