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;
}


Digital Etch-A-Sketch by Mattias Green

A simple but effective project to demonstrate physical control over a computer screen.

  1. Connect two potentiometers to Arduino analog inputs A0 and A1
  2. Use serial-communications to get pot values from Arduino to Processing
  3. Make a Processing sketch that accepts the serial data and draws lines

 Arduino Code

void setup() {
  // Start serial-communications with computer:
  Serial.begin(9600); 
}

void loop() {
  delay(1);
  int sensorValueA = analogRead(A0); // Read pot at pin A0
  delay(1); // Wait between AD-conversions
  int sensorValueB = analogRead(A1); // Read pot at pin A1
  
  // Send variable contents over serial:
  Serial.print(sensorValueA);
  Serial.print(",");
  Serial.println(sensorValueB);
  // The formatting above is important when using more 
  // than one variable
}

Please take a moment to think about how the variable values will be presented to Processing. You cannot just Serial.println(var1); Serial.println(var2); If you’d do that, there would be no way for processing to know which value comes from which variable. To help parsing the data in Processing, print the values on the same line, separated by a comma.

Now, processing will se your two values like this: 233,856 and they will be considered a text String, not numeric values. (233 would be the value at Arduino pin A0 and 856 at A1.) You can easily convert such a string of words delimited by commas into an array of words.  Use split(str,delimiter) in Processing. “233,856” will be converted to [“233”, “856”] and each item can be accessed individually, and treated as a numeric value.

Processing Code

Serial myPort; // Use the serial port:
 
float prevX = -1; // Store pot values here
float prevY = -1;

void setup() {
  size(1024, 800); // Set screen size
 
  println(Serial.list()); // Print all available serial ports. Figure out which one the arduino uses.
  myPort = new Serial(this, Serial.list()[5], 9600); // The [5] refers to the 6th serial port in the list
  myPort.bufferUntil('\n');

  strokeWeight(5);
  stroke(50); // Color
}

void draw() {
	// Nothing
}

void serialEvent(Serial myPort) {
  // This could probably be optimized a bit, 
  // but I don't have Processing at hand right now..
  String inString = myPort.readString();   // Read a string from the serial port
  String[] inValues = split(inString, ','); // Split comma separated string to array of strings
  float inX = float(inValues[0]); // Convert array item at index 0 to a float number 
  float inY = float(inValues[1]); // Convert array item at index 1 
  
  if((inX != prevX) || (inY != prevY)) { // Not necessary, this is to avoid drawing if pots haven't changed
    if((prevX > -1) && (prevY > -1)) {
      line(prevX, prevY, inX, inY); // Draw a line from the last recorded pot values to the current ones
    }
    prevX = inX; // Store the new pot values for next draw cycle
    prevY = inY;
  }
}

 

Proof of Concept ;)

(Does not work in Firefox for some WordPress-related reason)

 

Week 7 2015 Forsbergs Arduino Course

Four days of electronics and programming

You know you love it. The course contents were essentially the same as this course, and followed the posts on this site.

We also found a few errors in the posts, so I had an opportunity to correct them. Thank you Forsbergs Design 2 2014-2015 for beta testing ;)

Some of the students connected Processing IDE (on the Mac) to an Arduino using the serial-communications. Thus, the Arduino became an interface to Processing’s on-screen drawing tools. For an example, see this student project by Mattias Green.

A distant colleague of mine happened to have an Arduino course at the same time. They also connected Arduino to Processing, to enable physical control over audio sample playback on the computer.

Week 50 2014 Forsbergs Arduino Course

A one-week crash-course

…in electronics and programming. This is the kit we used for the course:

1602 LCD Servo Dot Matrix Breadboard LED Resistor UNO R3 Starter Kit for Arduino (eBay)

We did not use most of the advanced stuff in it. I also added a couple of components:

  • One solenoid: 12 volts, the strongest and longest slew I could find for a reasonable price (eBay)
  • One transistor: TIP120 60V / 5A (electrokit)
  • One high power diode: 1N4001, 50V / 1A (electrokit)
  • One power adapter 12V / 5A (eBay)

A few other things need to be added, for example a couple of decoupling capacitors, 0.1µF and 10µF, and maybe a fat electrolyte for smoothing out effects of sudden power draws.

Original kit contents:
1 x UNO R3 Mainboard
1 x USB Cable (30cm HIGH QUALITY,color could be blue or black,base on stock type)
1 x Extension Board with mini breadboard
1 x 830 Contact Points Breadboard
1 x 5mm LED Assorted Kit (Red/Green/Yellow 10pcs each + White 5pcs + RGB Trip-color 1Piece)
1 x 8bit Shift Register 74hc595
1 x MAX7219 Chip
2 x Buzzer 5v (1 active and 1 passive)
1 x Eight-segment Display (1-digit Common Anode)
1 x Eight-segment Display (4-digit Common Anode) with clock
10 x Push Button Switch 12*12mm
5 x Mini Push Button Switches 6*6mm
1 x Light Dependent Resistor (photocell)
20 x 10KΩ Resistor
20 x 220Ω Resistor
5 x 1kΩ Resistor
1 x 5k Trimpot Adjustable Resistor Potentiometer
1 x 10k Trimpot Adjustable Resistor Potentionmeter
1 x LM35 Temperature Sensor
1 x 1602 LCD Display
1 x PS2 Joystick Module
1 x Stepping Motor 5v
1 x Stepping Motor Driver Board
1 x SG90 Servo Motor
1 x RGB Module
65 x Jumper Wires
10 x Dupont Lines(Female to Female)
1 x 2.54mm Straight 40 Pin Header
1 x 2.54mm Elbow 40 Pin Header
1 x Mercury Switches
1 x Flame Sensor
1 x Infrared Sender
1 x Infrared Receiver
1 x Remote Controler (Battery- CR2025 Not Included)
1 x 8*8 Dot Matrix Display
1 x 5v 10A Relay Module with optocouple
1 x DC 9v Battery Button Cable (Battery-9V Not Included)


Additional info

SainSmart UNO R3 – Arduino Forum Lessons for a similar kit. The advanced lessons are not covered in this blog yet.

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);
}