Thursday, December 25, 2014

Raspberry Pi + Arduino i2c communication, write block and read byte

In this example Raspbery Pi (programmed with Python) is connected with Arduino Uno via I2C. The Raspberry Pi act as i2c master, and Arduino act as i2c slave. Raspberry Pi send block of data to Arduino, and read byte echo from Arduino.

Read my another blog for the source code: http://helloraspberrypi.blogspot.com/2014/12/raspberry-pi-arduino-i2c-communication.html


Monday, December 22, 2014

Generate sin wave on Arduino Due

Example to generate sin wave on DAC pin of Arduino Due.


#define maxSamplesNum 120

static int sinwave[maxSamplesNum] = {
  0x7ff, 0x86a, 0x8d5, 0x93f, 0x9a9, 0xa11, 0xa78, 0xadd, 0xb40, 0xba1,
  0xbff, 0xc5a, 0xcb2, 0xd08, 0xd59, 0xda7, 0xdf1, 0xe36, 0xe77, 0xeb4,
  0xeec, 0xf1f, 0xf4d, 0xf77, 0xf9a, 0xfb9, 0xfd2, 0xfe5, 0xff3, 0xffc,
  0xfff, 0xffc, 0xff3, 0xfe5, 0xfd2, 0xfb9, 0xf9a, 0xf77, 0xf4d, 0xf1f,
  0xeec, 0xeb4, 0xe77, 0xe36, 0xdf1, 0xda7, 0xd59, 0xd08, 0xcb2, 0xc5a,
  0xbff, 0xba1, 0xb40, 0xadd, 0xa78, 0xa11, 0x9a9, 0x93f, 0x8d5, 0x86a,
  0x7ff, 0x794, 0x729, 0x6bf, 0x655, 0x5ed, 0x586, 0x521, 0x4be, 0x45d,
  0x3ff, 0x3a4, 0x34c, 0x2f6, 0x2a5, 0x257, 0x20d, 0x1c8, 0x187, 0x14a,
  0x112, 0xdf, 0xb1, 0x87, 0x64, 0x45, 0x2c, 0x19, 0xb, 0x2,
  0x0, 0x2, 0xb, 0x19, 0x2c, 0x45, 0x64, 0x87, 0xb1, 0xdf,
  0x112, 0x14a, 0x187, 0x1c8, 0x20d, 0x257, 0x2a5, 0x2f6, 0x34c, 0x3a4,
  0x3ff, 0x45d, 0x4be, 0x521, 0x586, 0x5ed, 0x655, 0x6bf, 0x729, 0x794
};

int i = 0;

void setup() {
  analogWriteResolution(12);
}

void loop() {
  i++;
  if(i == maxSamplesNum)
    i = 0;
    
  analogWrite(DAC1, sinwave[i]);
}

Sunday, December 21, 2014

Assemble, test, align and power-up DSO138, Open-sourced Oscilloscope DIY kit



Just purchased a Open-source Oscilloscope DIY kit DSO138, with surface mount components soldered. Here how I assembled it in 2 hours.


After assembled, check voltage on TP22. Make sure it is arround 3.3V. Then short JP4 and install LCD module.


Notice: This video recorded after my final tested, so JP4 have been shorted at beginning. Actually, you have to keep it open after 3.3V on TP22 confirmed.

After the kit worked, align the 0V line and calibrate the probe.





For details and update of the DSO 138 DIY Kit, read Users Manual on the website.

Tested with Arduino Due generated sin wave.



Tuesday, December 16, 2014

Raspberry Pi send block of data to Arduino using I2C


Raspberry Pi act as I2C master to send block of data to Arduino Uno. In Arduino side, act as I2C slave, display received message on 16x2 LCD display.
http://helloraspberrypi.blogspot.com/2014/12/raspberry-pi-send-block-of-data-to.html


Sunday, December 14, 2014

Raspberry Pi write I2C data to Arduino Uno

A step-by-step example to implement communiation between Raspberry Pi and Arduino using I2C. Here Raspberry Pi, programmed with Python, act as I2C host and Arduino Uno act as slave.

Wednesday, December 10, 2014

Open-sourced DSO (Digital Storage Oscilloscope) DIY kit - DSO138

Interesting open-sourced digital oscilloscope DIY kit, DSO138, think about buying one. But I can't find the source in the web-site, and instruction to flash the firmware!



http://www.jyetech.com/Products/LcdScope/e138.php

DSO138 was designed as a training oscilloscope kit. It contains only the basical oscilloscope functions with no fancy features. Simplicity in structure and easiness in assembly/operation are among the main targets of the design. For these purpose DSO138 uses mostly through-hole parts. The heart of DSO138 is a Cortex-M3 ARM processor (STM32F103C8) from ST. It uses 2.4-inch TFT LCD (320 X 240 dotmatrix, 262K colors) as its display element and displays nice and clear waveforms. Detailed assembly instructions are provided in combination with troubleshooting guide and schematc. Source codes are also available to allow user to add their own features.

DSO138 kits are solded in two configurations. One is with all SMD parts pre-soldered (PN: 13801K). The other is with only the main IC (the MCU) pre-soldered (PN: 13802K). The latter serves also as a SMD soldering training kit. For both configurations the MCU has been pre-programmed and no re-programming required.

DSO138 is partially open-sourced. This opens the possibility for users to add different features or develop new applications on the hardware.

Major features of DSO138: 
  • Analog bandwidth: 0 - 200KHz
  • Sampling rate: 1Msps max
  • Sensitivity: 10mV/Div - 5V/Div
  • Sensitivity error: < 5%
  • Vertical resolution: 12-bit
  • Timebase: 10us/Div - 500s/Div
  • Record length: 1024 points
  • Built-in 1KHz/3.3V test signal
  • Waveform frozen (HOLD) function available


Updated:
Finally I bought my own DSO138 kit, read Assemble, test, align and power-up DSO138, Open-sourced Oscilloscope DIY kit.

Monday, December 8, 2014

Program Arduino Pro Mini with USB-to-Serial adapter

This is a good video tutorial for programming (or flash) Arduino Pro Mini with USB-to-Serial adapter. Using 3 different USB to Serial modules to program a clone Arduino Pro Mini. The chips are the FTDI FT232RL, the Silicon Labs CP2102 and the Prolific Technologies PL2032HX.



HC-05 Serial Port Bluetooth Module (Master/Slave)

HC-05 module is an easy to use Bluetooth SPP (Serial Port Protocol) module, designed for transparent wireless serial connection setup.


Serial port Bluetooth module is fully qualified Bluetooth V2.0+EDR (Enhanced Data Rate) 3Mbps Modulation with complete 2.4GHz radio transceiver and baseband. It uses CSR Bluecore 04-External single chip Bluetooth system with CMOS technology and with AFH(Adaptive Frequency Hopping Feature). It has the footprint as small as 12.7mmx27mm. Hope it will simplify your overall design/development cycle.




Sunday, December 7, 2014

Arduino ISP

The Arduino ISP (http://arduino.cc/en/Main/ArduinoISP) is a tiny AVR-ISP (in-system programmer) based on David Mellis' project FabISP (http://fab.cba.mit.edu/content/projects/fabisp/). With this programmer you can upload sketches and burn the bootloader on any AVR based boards, including Arduinos. By uploading a sketch with an external programmer you can remove the bootloader and use the extra space for your sketch. The Arduino ISP can also be used to burn the Arduino bootloader, so you can recover your chip if you accidentally corrupt the bootloader. Burning the bootloader is also necessary when you use a new ATmega microcontroller in your Arduino, and you wish to use the bootloader to upload a sketch via the USB-Serial connection.

For more details about using the Arduino ISP please visit the Getting Started page.


Sunday, November 30, 2014

10 Hot Internet of Things Startups

As Internet connectivity gets embedded into every aspect of our lives, investors, entrepreneurs and engineers are rushing to cash in. Here are "10 Hot Internet of Things (IoT) Startups", selected by CIO Magazine.

  1. AdhereTech: Provide a connected pill bottle that ensures patients take their medications.
  2. Chui: Combine facial recognition with advanced computer vision and machine learning techniques to turn faces into "universal keys." Chui refers to its solution as "the world's most intelligent doorbell."
  3. Enlighted: Provide a smart lighting system.
  4. Heapsylon: Turn clothes into computers.
  5. Humavox: Create technologies to wirelessly power IoT by using radio frequencies, thus eliminating the need for wires.
  6. Neura: Neura's goal is to become the "glue connecting the Internet of Things" by developing an open platform that bridges objects, locations, people and the Web.
  7. PubNub: Provide a global real-time network that "solves the problems of large-scale IoT connectivity in the wild, enabling IoT providers to focus on their core businesses."
  8. Revolv: Unifies control of your smart home via a smartphone or tablet app.
  9. TempoDB: Provide a cloud-based sensor data analytics backend for IoT and M2M.
  10. Theatro: Provide small Wi-Fi based wearable devices intended for indoor communications within the enterprise.

source: CIO - 10 Hot Internet of Things Startups

Friday, November 21, 2014

Arduino BASIC - a BASIC interpreter running on an Arduino

Now you can turn your Arduino into an 80's home computer!

A complete BASIC interpreter for the Arduino, using a PS/2 keyboard, and SPI OLED screen. The BASIC supports almost all the usual features, with float and string variables, multi-dimensional arrays, FOR-NEXT, GOSUB-RETURN, etc. Saving and Loading from EEPROM is supported, as well as auto-running a program on power-up. You can also read and write from the analog and digital pins.

There's about 1k of RAM available for your BASIC programs and variables, so its roughly equivalent to my first computer (a Sinclair ZX81). The other 1k of RAM (on an UNO) is used for the keyboard and screen buffers, with a small bit of room left for the CPU stack. That works out quite well, since there's a 1k EEPROM on the arduino so if your program fits in the basic environment, it will fit when saved to EEPROM!

https://github.com/robinhedwards/ArduinoBASIC


Thursday, November 13, 2014

Wednesday, November 5, 2014

The Maker's Manual, powered by Intel

About The Maker’s Manual

The Maker’s Manual explores how everyone from do-it-yourselfers and artists to inventors and entrepreneurs are leveraging new tools, platforms and services to take their ideas from concepts to reality.

In our Democratized Creation theme we explore how the hardware and tools required to start building DIY technology projects are becoming more widely available, cost-effective and user friendly, encouraging a greater number of people to become involved in the Maker Movement regardless of their knowledge and level of skill. With the Community Exchange theme we look at how a growing number of digital platforms and physical spaces are helping to cultivate the Maker Movement by bringing people together to share essential knowledge and resources, while simultaneously creating new marketplaces for buying and selling their products.

The report, underwritten by Intel, also looks at Growth Systems and explores how a new set of services are allowing the Maker community to take their projects from personal passions to full-fledged product lines by providing flexible and cost-effective access to financial capital, copyright management tools and manufacturing facilities. Within these themes, we take an in-depth look at ten key trends, bringing them to life with best-in-class examples, constructing unique user experience paths for readers to navigate them based on their level of involvement in the Maker Movement. As you click through the following pages, we hope you find inspiration and innovation that you can leverage and share.

The Maker's Manual

or visit http://www.slideshare.net/PSFK/makers-manual

Tuesday, November 4, 2014

Use jSSC (Java Simple Serial Connector) on Windows 8.1

jSSC (Java Simple Serial Connector) is a library for working with serial ports from Java. jSSC support Win32(Win98-Win8), Win64, Linux(x86, x86-64, ARM), Solaris(x86, x86-64), Mac OS X 10.5 and higher(x86, x86-64, PPC.

My old post show how to Install and test java-simple-serial-connector with Arduino, running on Ubuntu and Netbeans IDE.

This video show how to use jSSC on Windows 8.1/Nerbeans IDE. Basically it is the same, with different COM port assignment.


The Java code is listed here. It send a message to Arduino Esplora via USB Serial port, COM3, using jSSC library.

package java_testjssc;
 
import jssc.SerialPort;
import jssc.SerialPortException;
 
public class Java_testjSSC {
 
    public static void main(String[] args) {
        SerialPort serialPort = new SerialPort("COM3");
        try {
            System.out.println("Port opened: " + serialPort.openPort());
            System.out.println("Params setted: " 
                + serialPort.setParams(9600, 8, 1, 0));
            System.out.println("\"Hello World!!!\" successfully writen to port: " 
                + serialPort.writeBytes("Hello World!!!".getBytes()));
            System.out.println("Port closed: " 
                + serialPort.closePort());
        }
        catch (SerialPortException ex){
            System.out.println(ex);
        }
    }
     
}

The Arduino side code, refer to the post "Serial communication between Arduino Esplora and PC".



Wednesday, October 22, 2014

Smartwatch with laser projected Skin Buttons

Future Interfaces Group present Skin Buttons, tiny laser projectors integrated into the smartwatch to render icons on the user’s skin. These icons can be made touch sensitive, significantly expanding the interactive region without increasing device size. This video show a proof-of-concept device and demonstrate example applications. These “skin buttons” can have high touch accuracy and recognizability, while being low cost and power-efficient.

http://www.figlab.com

Monday, October 20, 2014

LinkIt ONE

The LinkIt ONE development board is an open source, high performance board for prototyping Wearables and IoT devices. It's based on the world’s leading SoC for Wearables, MediaTek Aster (MT2502) combined with high performance Wi-Fi (MT5931) and GPS (MT3332) chipsets to provide you with access to all the features of MediaTek LinkIt. It also provides similar pin-out features to Arduino boards, making it easy for you to connect to various sensors, peripherals, and Arduino shields.

LinkIt ONE is a co-design product by Seeed Studio and MediaTek. It brings together the parties’ knowledge in open hardware and industry leading reference designs for Wearables and IoT devices to create this powerful development board.

know more: http://www.seeedstudio.com/wiki/LinkIt_ONE

Sunday, October 19, 2014

Thursday, October 16, 2014

Hong Kong Mini Maker Faire 2014

Hong Kong Mini Maker Faire 2014
The Hong Kong Maker Club
Saturday, October 18, 2014 at 10:00 AM - Sunday, October 19, 2014 at 6:00 PM (HKT)

http://www.eventbrite.hk/e/hong-kong-mini-maker-faire-2014-tickets-13221863951

Monday, September 29, 2014

First wearable drone camera, by Team Nixie

Team Nixie is developing the first wearable drone camera, which can be worn around your wrist. The team will be presenting their prototype for the Intel Make It Wearable Challenge Finale on November 3, 2014 in San Francisco. Learn more about Make It Wearable and follow the race to the finish line at http://makeit.intel.com.

To find out more about Team Nixie, see their work at flynixie.com or follow them on https://www.facebook.com/flynixie.

Make It Wearable Finalists | Meet Team Nixie

Friday, September 26, 2014

Esplora TFT work on Arduino Uno

The Arduino TFT screen is a backlit LCD screen with headers, designed to fit Arduino Esplora or the Arduino Robot. This module is also compatible with any AVR-based Arduino (Uno, Leonardo, etc...) or with the Arduino Due. Read Connecting to other Arduino boards for more details.

This example, TFTGraph, run on Arduino Uno board, reads the value of analog input on A0, and graphs the values on the screen.


To connect Arduino TFT to Arduino Uno board:


Run example of TFTGraph example from Arduino IDE, File > Examples > TFT > Arduino > TFTGraph.

/*

 TFT Graph

 This example for an Arduino screen reads
 the value of an analog sensor on A0, and
 graphs the values on the screen.

 This example code is in the public domain.

 Created 15 April 2013 by Scott Fitzgerald

 http://arduino.cc/en/Tutorial/TFTGraph

 */

#include <TFT.h>  // Arduino LCD library
#include <SPI.h>

// pin definition for the Uno
#define cs   10
#define dc   9
#define rst  8

// pin definition for the Leonardo
// #define cs   7
// #define dc   0
// #define rst  1

TFT TFTscreen = TFT(cs, dc, rst);

// position of the line on screen
int xPos = 0;

void setup() {
  // initialize the serial port
  Serial.begin(9600);

  // initialize the display
  TFTscreen.begin();

  // clear the screen with a pretty color
  TFTscreen.background(250, 16, 200);
}

void loop() {
  // read the sensor and map it to the screen height
  int sensor = analogRead(A0);
  int drawHeight = map(sensor, 0, 1023, 0, TFTscreen.height());

  // print out the height to the serial monitor
  Serial.println(drawHeight);

  // draw a line in a nice color
  TFTscreen.stroke(250, 180, 10);
  TFTscreen.line(xPos, TFTscreen.height() - drawHeight, xPos, TFTscreen.height());

  // if the graph has reached the screen edge
  // erase the screen and start again
  if (xPos >= 160) {
    xPos = 0;
    TFTscreen.background(250, 16, 200);
  }
  else {
    // increment the horizontal position:
    xPos++;
  }

  delay(16);
}


Wednesday, September 24, 2014

Communication between Android and Arduino Uno in USB Host Mode

It's Bi-directional communication between Android and Arduino in USB Host Mode.

Example 1:
Single byte is sent between Android and Arduino to control LED on Arduino Uno borad and set SeekBar on Android screen according to potentiometer on Arduino. ~ http://android-er.blogspot.com/2014/09/bi-directional-communication-between.html



Example 2:
Communication sent as commands form, to set Arduino LED, and send string of text from Android to Arduino LCD, and echo back. ~ http://android-er.blogspot.com/2014/09/bi-directional-communication-between_24.html


Saturday, September 20, 2014

Firmata + Python/pyFirmata, control Arduino from Raspberry Pi

This post show steps to install pyFirmata, and also python-serial, on Raspberry Pi. Such that we can program Arduino Uno (with StandardFirmata sketch) using Python.

- Make sure you have Arduino IDE installed on Raspberry Pi.

- Install pyFirmata and python-serial, enter the command in Terminal.
$ sudo apt-get install python-pip python-serial
$ sudo pip install pyfirmata


To test your setup:

- Upload StandardFirmata sketch to your Arduino.
In Arduino IDE, click File > Examples > Firmata > StandardFirmata
Compile and upload the sketch to Arduino Uno.

- Try on Python IDLE
Start icon > Programming > IDLE to start Python
Enter the code:
>>> from pyfirmata import Arduino, util
>>> board = Arduino('/dev/ttyACM0')
>>> board.digital[13].write(1)
>>> board.digital[13].write(0)


Arduino IDE on Raspberry Pi


To install Arduino IDE on Raspberry Pi, run the command on Terminal:
$ sudo apt-get install arduino

Friday, September 19, 2014

Communication between Arduinos on I2C using Wire Library

Example to implement I2C communiation between Arduino Uno, using Wire Library.


Connection:


I2CMaster.ino
#include <Wire.h>

#define LED_PIN 13
byte CMD_ON = 0x00;
byte CMD_OFF = 0x01;
byte cmd = CMD_OFF;

byte slave_address = 7;

void setup()
{
  // Start I2C Bus as Master
  Wire.begin(); 
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);

}
void loop()
{
  if(cmd == CMD_OFF){
    delay(500);
    cmd = CMD_ON;  //prepare next cmd
  }else{
    delay(1500);
    cmd = CMD_OFF;  //prepare next cmd
  }
  
  Wire.beginTransmission(slave_address);
  Wire.write(cmd);
  Wire.endTransmission();
}

I2CSlave.ino
#include <Wire.h>

#define LED_PIN 13

//7-bit slave address (optional)
byte slave_address = 7;
byte CMD_ON = 0x00;
byte CMD_OFF = 0x01;

void setup() {
  // Start I2C Bus as Slave
  Wire.begin(slave_address);
  Wire.onReceive(receiveEvent);
  
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);  

}

void loop() {

}

void receiveEvent(int howMany) {
  byte cmd = Wire.read();
  if (cmd == CMD_ON){
    digitalWrite(LED_PIN, HIGH);
  }else if(cmd == CMD_OFF){
    digitalWrite(LED_PIN, LOW);
  }
}

Reference: Wire Library

Thursday, September 18, 2014

Arduino Launches an Open-Source Apartment


Located in their Torino, Italy headquarters, Arduino and futurist Bruce Sterling are building an experimental showcase apartment, outfitted with open-source hardware and furniture. But unlike the “homes of the future” of past years, this one will be available to rent via AirBnb. 

Make’s Mike Senese catches up with Arduino co-founder Massimo Banzi at MakerCon to get the details and hear about the other endeavors coming from the makers of the popular microcontrollers.


The smart dancing traffic light

The Dancing Traffic Light


Making of:

Communication betweeen Arduinos using SPI


This example show how to communicate between two Arduino Uno using SPI. The connection is shown here:


On Master side, any data received from Serial (PC), it will be sent to slave Arduino using SPI. And data received from slave will be sent to Serial (PC).

SPIMaster.ino
#include <SPI.h>
byte dataOut;
byte dataIn;

int pinSS = 10;  //Slave Select, active LOW

void setup(){
  Serial.begin(115200);  //link to PC
  
  pinMode(pinSS, OUTPUT);
  digitalWrite(pinSS, HIGH);
  SPI.begin();
}

void loop(){
  while(Serial.available() > 0){
    dataOut = Serial.read();
    dataIn = spiWriteAndRead(dataOut);
    Serial.write(dataIn);
  }
}

byte spiWriteAndRead(byte dout){
  byte din;
  digitalWrite(pinSS, LOW);
  delay(1);
  din = SPI.transfer(dout);
  digitalWrite(pinSS, HIGH);
  return din;
}

On Slave side, any data received from SPI will be sent to Serial (PC) and echo back to master Arduino in next round of transmission.

SPISlave.ino
byte dataEcho;  //echo back input data in next round
byte dataToPC;  //send input data to PC

void setup() {
    Serial.begin(115200);  //link to PC
    
    //The Port B Data Direction Register
    DDRB  |= 0b00010000; 
   //The Port B 
    PORTB |= 0b00000100;
    
    //SPI Control Register
    SPCR  |= 0b11000000;
    //SPI status register
    SPSR  |= 0b00000000;
    
    dataEcho = 0;
    dataToPC = 0;
    
    sei();
}

void loop() {
  
  if(dataToPC != 0){
    Serial.write(dataToPC);
    dataToPC = 0;
  }

}

ISR(SPI_STC_vect){
  cli();
  
  //while SS Low
  while(!(PINB & 0b00000100)){
    SPDR = dataEcho;
    
    //wait SPI transfer complete
    while(!(SPSR & (1 << SPIF)));
    
    dataEcho = SPDR;  //send back in next round
  }
  sei();
}

Sunday, September 14, 2014

Intel Edison Development Platform: Getting Started

This video take you through a step-by-step process to get up and running with Intel Edison technology.

Tuesday, September 9, 2014

Arduino Uno: scan LED Matrix in Timer Interrupt

The original tutorial "Row-columm Scanning to control an 8x8 LED Matrix" call refreshScreen() to draw the screen repeatly in main loop(). If anything in loop() have to do something for times, will block the program, and make the duty cycle (and the brightness) will become unstable. This example show how to scan LED Matrix in Timer Interrupt ISR, such that it will not be affect by the jobs in loop(). But the timing of Timer Interrupt will affect the performance. This video show how:



// 2-dimensional array of row pin numbers:
const int row[8] = {
  2, 7, 19, 5, 13, 18, 12, 16
};

// 2-dimensional array of column pin numbers:
const int col[8] = {
  6, 11, 10, 3, 17, 4, 8, 9
};

// 2-dimensional array of pixels:
int pixels[8][8];

int posX = 7;
int posY = 7;
int count = 30;
bool bg = false;

unsigned int timer1_counter;
int scanningRow = 0;

void setup() {
  Serial.begin(9600);
  
  // initialize the I/O pins as outputs
  // iterate over the pins:
  for (int thisPin = 0; thisPin < 8; thisPin++) {
    // initialize the output pins:
    pinMode(col[thisPin], OUTPUT);
    pinMode(row[thisPin], OUTPUT);
    // take the col pins (i.e. the cathodes) high to ensure that
    // the LEDS are off:
    digitalWrite(col[thisPin], HIGH);
  }

  // initialize timer1 
  noInterrupts();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;

  //timer1_counter for 1 sec, with prescaler=256
  //65536 - 16000000/256
  //timer1_counter = 3036;
  //timer1_counter for 0.5 sec, with prescaler=256
  //65536 - 16000000/(256*2)
  //timer1_counter = 34286;
  //timer1_counter for 0.1 sec, with prescaler=256
  //65536 - 16000000/(256*10)
  //timer1_counter = 59286;
  //timer1_counter for 0.001 sec, with prescaler=256
  //65536 - 16000000/(256*100)
  //timer1_counter = 64911;
  //timer1_counter for 0.0002 sec, with prescaler=256
  //65536 - 16000000/(256*500)
  timer1_counter = 65411;
  
  TCNT1 = timer1_counter;   // preload timer
  TCCR1B |= (1 << CS12);    // 256 prescaler 
  TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
  interrupts();             // enable all interrupts
  
  //init pixels
  for (int x = 0; x < 4; x++) {
    for (int y = 0; y < 8; y++) {
      pixels[x][y] = HIGH;
    }
  }
  for (int x = 4; x < 8; x++) {
    for (int y = 0; y < 8; y++) {
      pixels[x][y] = LOW;
    }
  }
  
  pixels[1][3] = LOW;

}

ISR(TIMER1_OVF_vect)        // interrupt service routine 
{
  TCNT1 = timer1_counter;   // preload timer

  
  //scan LED Matrix in ISR
  digitalWrite(row[scanningRow], LOW);

  if(++scanningRow>=8){
    scanningRow = 0;
  }

  for (int thisCol = 0; thisCol < 8; thisCol++) {
    int thisPixel = pixels[scanningRow][thisCol];
    digitalWrite(col[thisCol], thisPixel);
  }
  digitalWrite(row[scanningRow], HIGH);
  
}

void loop() {
  //refreshScreen();
  
  //Do something, block the loop
  Serial.println("Hello!");
  //Serial.println("Hello! again");

}

void refreshScreen() {
  // iterate over the rows (anodes):
  for (int thisRow = 0; thisRow < 8; thisRow++) {
    // take the row pin (anode) high:
    digitalWrite(row[thisRow], HIGH);
    // iterate over the cols (cathodes):
    for (int thisCol = 0; thisCol < 8; thisCol++) {
      // get the state of the current pixel;
      int thisPixel = pixels[thisRow][thisCol];
      // when the row is HIGH and the col is LOW,
      // the LED where they meet turns on:
      digitalWrite(col[thisCol], thisPixel);
      // turn the pixel off:
      if (thisPixel == LOW) {
        digitalWrite(col[thisCol], HIGH);
      }
    }
    // take the row pin low to turn off the whole row:
    digitalWrite(row[thisRow], LOW);
  }
}

Monday, September 8, 2014

Using Timer Interrupt of Arduino Uno

Example to use Timer Interrupt of Arduino Uno.


WalkingLedMatrix.ino
// 2-dimensional array of row pin numbers:
const int row[8] = {
  2, 7, 19, 5, 13, 18, 12, 16
};

// 2-dimensional array of column pin numbers:
const int col[8] = {
  6, 11, 10, 3, 17, 4, 8, 9
};

// 2-dimensional array of pixels:
int pixels[8][8];

int posX = 7;
int posY = 7;
int count = 30;
bool bg = false;

volatile unsigned long lasttime;
volatile unsigned long now;

int timer1_counter;

void setup() {
  Serial.begin(9600);
  
  // initialize the I/O pins as outputs
  // iterate over the pins:
  for (int thisPin = 0; thisPin < 8; thisPin++) {
    // initialize the output pins:
    pinMode(col[thisPin], OUTPUT);
    pinMode(row[thisPin], OUTPUT);
    // take the col pins (i.e. the cathodes) high to ensure that
    // the LEDS are off:
    digitalWrite(col[thisPin], HIGH);
  }

  setupScreen();
  
  // initialize timer1 
  noInterrupts();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;

  //timer1_counter for 1 sec, with prescaler=256
  //65536 - 16000000/256
  //timer1_counter = 3036;
  //timer1_counter for 0.5 sec, with prescaler=256
  //65536 - 16000000/(256*2)
  //timer1_counter = 34286;
  //timer1_counter for 0.1 sec, with prescaler=256
  //65536 - 16000000/(256*10)
  timer1_counter = 59286;
  
  
  TCNT1 = timer1_counter;   // preload timer
  TCCR1B |= (1 << CS12);    // 256 prescaler 
  TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
  interrupts();             // enable all interrupts
  
  lasttime = millis();

}

ISR(TIMER1_OVF_vect)        // interrupt service routine 
{
  TCNT1 = timer1_counter;   // preload timer

  if(posX--==0){
    posX = 7;
    if(posY--==0){
      posY = 7;
      bg = !bg;
    }
  }
  setupScreen();
  
  now = millis();
  Serial.println(now - lasttime);
  lasttime = now;
}

void loop() {
  refreshScreen();
}

void setupScreen(){
  if(bg){
    //ON all others
    for (int x = 0; x < 8; x++) {
      for (int y = 0; y < 8; y++) {
        pixels[x][y] = LOW;
      }
    }
    
    //OFF current pos
    pixels[posX][posY] = HIGH;
  }else{
    //OFF all others
    for (int x = 0; x < 8; x++) {
      for (int y = 0; y < 8; y++) {
        pixels[x][y] = HIGH;
      }
    }
    
    //ON current pos
    pixels[posX][posY] = LOW;
  }
}

void refreshScreen() {
  // iterate over the rows (anodes):
  for (int thisRow = 0; thisRow < 8; thisRow++) {
    // take the row pin (anode) high:
    digitalWrite(row[thisRow], HIGH);
    // iterate over the cols (cathodes):
    for (int thisCol = 0; thisCol < 8; thisCol++) {
      // get the state of the current pixel;
      int thisPixel = pixels[thisRow][thisCol];
      // when the row is HIGH and the col is LOW,
      // the LED where they meet turns on:
      digitalWrite(col[thisCol], thisPixel);
      // turn the pixel off:
      if (thisPixel == LOW) {
        digitalWrite(col[thisCol], HIGH);
      }
    }
    // take the row pin low to turn off the whole row:
    digitalWrite(row[thisRow], LOW);
  }
}

Tuesday, September 2, 2014

Node.js send string to Arduino Uno

Example to send Hello message from Node.js to Arduino Uno. Due to the Automatic (Software) Reset on Arduino Uno board, it will be reset Node.js open a SerialPort. So we have to insert a dummy delay (3 sec in the example) before first string sent.

reference:
Arduino Uno
DisablingAutoResetOnSerialConnection


Node.js code, nodejsUno.js
//To install 'serialport' locally, enter the command:
//$ npm install serialport
//Otherwise, Error: Cannot find module 'serialport' will reported

var SerialPort = require("serialport").SerialPort
var serialPort = new SerialPort('/dev/ttyACM0', 
    {   baudrate: 9600
    });
 
serialPort.on("open", function () {
    console.log('open');

    
    setTimeout(function() {
        serialPort.write("Hello...", function(err, results) {
            console.log('err ' + err);
            console.log('results ' + results);
        });
        
        setTimeout(function() {
            serialPort.write("...from Node.js", function(err, results) {
                console.log('err ' + err);
                console.log('results ' + results);
            });     
        }, 1000);
        
    }, 3000);
    

});

Sketch on Arduino Uno, refer to the post "Read from Arduino Serial port, and write to 2x16 LCD".


Communication between Android and Arduino Uno, in USB Host Mode

It's a example to implement communication between Android and Arduino Uno. Here Android is running in USB Host Mode. String received in Arduino Uno is displayed on 2x16 LCD Module.

Android side, refer to the post "Send data from Android to Arduino Uno, in USB Host Mode" of my Android blog.

Arduino Uno side, refer to last post "Read from Arduino Serial port, and write to 2x16 LCD".


Friday, August 29, 2014

Read from Arduino Serial port, and write to 2x16 LCD

Read from Serial port of Arduino Uno, and write it to 2x16 LCD module.



/*

  http://arduino-er.blogspot.com/

  Example of using 16x2 LCD display
  Read from Arduino Serial port, and write to 2x16 LCD

 */

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
  
  Serial.begin(9600);
}

void loop() {
  if(Serial.available()){
    lcd.setCursor(0, 1);
    lcd.print("                ");
    delay(100);
    lcd.setCursor(0, 1);
    while(Serial.available() > 0){
      lcd.write(Serial.read());
    }
  }
}


Connection, refer:
Hello World of Arduino Uno + 2x16 LCD
- LED Backlight of 2x16 LCD Module

LED Backlight of 2x16 LCD Module

Refer to last post of "Hello World of Arduino Uno + 2x16 LCD" follow the tutorial "LiquidCrystal - Hello World!". And I found a LED on the LCD bracket, with marking A and K.


To turn on the LED backlight, connect +ve to pin 15 (marked A on my board), and -ve or GND to pin 16 (marked K on my board), as shown here:


Notice: Because it have not been shown on the connection diagram in tutorial "LiquidCrystal - Hello World!". You are suggested to check it on your on-hand LCD module.

Hello World of Arduino Uno + 2x16 LCD

The example of Arduino LiquidCrystal - "Hello World!" can be found here: http://www.arduino.cc/en/Tutorial/LiquidCrystal, or in Arduino IDE -> Examples -> LiquidCrystal -> HelloWorld.



/*
  LiquidCrystal Library - Hello World

 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.

 This sketch prints "Hello World!" to the LCD
 and shows the time.

  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)

 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 22 Nov 2010
 by Tom Igoe

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis() / 1000);
}


Connection:


Next:
LED Backlight of 2x16 LCD Module

Thursday, August 28, 2014

Port ASCII font to Arduino + 8*8 LED Matrix

https://github.com/dhepper/font8x8 is a collection of header files containing a 8x8 bitmap font. In this example, the font8x8_basic.h is port to Arduino, to display the 8x8 font on LED Matrix.



/*
 *  Modify from Row-Column Scanning an 8x8 LED matrix tutorial
 *  http://arduino-er.blogspot.com/
 */
 
 /*
  *  The 8x8 font is ported from 
  *  https://github.com/dhepper/font8x8/blob/master/font8x8_basic.h
  */

byte font[128][8] = {
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0000 (nul)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0001
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0002
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0003
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0004
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0005
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0006
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0007
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0008
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0009
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000A
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000B
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000C
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000D
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000E
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000F
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0010
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0011
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0012
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0013
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0014
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0015
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0016
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0017
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0018
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0019
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001A
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001B
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001C
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001D
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001E
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001F
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0020 (space)
    { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00},   // U+0021 (!)
    { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0022 (")
    { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00},   // U+0023 (#)
    { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00},   // U+0024 ($)
    { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00},   // U+0025 (%)
    { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00},   // U+0026 (&)
    { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0027 (')
    { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00},   // U+0028 (()
    { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00},   // U+0029 ())
    { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00},   // U+002A (*)
    { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00},   // U+002B (+)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06},   // U+002C (,)
    { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00},   // U+002D (-)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00},   // U+002E (.)
    { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00},   // U+002F (/)
    { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00},   // U+0030 (0)
    { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00},   // U+0031 (1)
    { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00},   // U+0032 (2)
    { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00},   // U+0033 (3)
    { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00},   // U+0034 (4)
    { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00},   // U+0035 (5)
    { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00},   // U+0036 (6)
    { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00},   // U+0037 (7)
    { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00},   // U+0038 (8)
    { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00},   // U+0039 (9)
    { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00},   // U+003A (:)
    { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06},   // U+003B (//)
    { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00},   // U+003C (<)
    { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00},   // U+003D (=)
    { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00},   // U+003E (>)
    { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00},   // U+003F (?)
    { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00},   // U+0040 (@)
    { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00},   // U+0041 (A)
    { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00},   // U+0042 (B)
    { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00},   // U+0043 (C)
    { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00},   // U+0044 (D)
    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00},   // U+0045 (E)
    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00},   // U+0046 (F)
    { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00},   // U+0047 (G)
    { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00},   // U+0048 (H)
    { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0049 (I)
    { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00},   // U+004A (J)
    { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00},   // U+004B (K)
    { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00},   // U+004C (L)
    { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00},   // U+004D (M)
    { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00},   // U+004E (N)
    { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00},   // U+004F (O)
    { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00},   // U+0050 (P)
    { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00},   // U+0051 (Q)
    { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00},   // U+0052 (R)
    { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00},   // U+0053 (S)
    { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0054 (T)
    { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00},   // U+0055 (U)
    { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},   // U+0056 (V)
    { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00},   // U+0057 (W)
    { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00},   // U+0058 (X)
    { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00},   // U+0059 (Y)
    { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00},   // U+005A (Z)
    { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00},   // U+005B ([)
    { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00},   // U+005C (\)
    { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00},   // U+005D (])
    { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00},   // U+005E (^)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF},   // U+005F (_)
    { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0060 (`)
    { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00},   // U+0061 (a)
    { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00},   // U+0062 (b)
    { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00},   // U+0063 (c)
    { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00},   // U+0064 (d)
    { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00},   // U+0065 (e)
    { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00},   // U+0066 (f)
    { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F},   // U+0067 (g)
    { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00},   // U+0068 (h)
    { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0069 (i)
    { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E},   // U+006A (j)
    { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00},   // U+006B (k)
    { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+006C (l)
    { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00},   // U+006D (m)
    { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00},   // U+006E (n)
    { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00},   // U+006F (o)
    { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F},   // U+0070 (p)
    { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78},   // U+0071 (q)
    { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00},   // U+0072 (r)
    { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00},   // U+0073 (s)
    { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00},   // U+0074 (t)
    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00},   // U+0075 (u)
    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},   // U+0076 (v)
    { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00},   // U+0077 (w)
    { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00},   // U+0078 (x)
    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F},   // U+0079 (y)
    { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00},   // U+007A (z)
    { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00},   // U+007B ({)
    { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},   // U+007C (|)
    { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00},   // U+007D (})
    { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+007E (~)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}    // U+007F
};

// 2-dimensional array of row pin numbers:
const int row[8] = {
  2, 7, 19, 5, 13, 18, 12, 16
};

// 2-dimensional array of column pin numbers:
const int col[8] = {
  6, 11, 10, 3, 17, 4, 8, 9
};

// 2-dimensional array of pixels:
int pixels[8][8];

int count = 1000;

//char str[] = "01234567890abcdefghijklmopqrstuvwxyz";

char str[] = {
  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 
  0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 
  0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 
  0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 
  0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
  0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 
  0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
  0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 
  0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
};

int strLen = sizeof(str);
int ptrChar = 0;

void setup() {

  
  // initialize the I/O pins as outputs
  // iterate over the pins:
  for (int thisPin = 0; thisPin < 8; thisPin++) {
    // initialize the output pins:
    pinMode(col[thisPin], OUTPUT);
    pinMode(row[thisPin], OUTPUT);
    // take the col pins (i.e. the cathodes) high to ensure that
    // the LEDS are off:
    digitalWrite(col[thisPin], HIGH);
  }
  
  setupChar();

}

void loop() {

  // draw the screen:
  refreshScreen();
  
  if(count-- == 0){
    count = 1000;
    setupChar();
  }

}

void setupChar(){

  char c = str[ptrChar];

  for (int x = 0; x < 8; x++) {
    byte bitMask = 0x01;
    byte f = font[c][x];
    for (int y = 0; y < 8; y++) {
      if (f & bitMask){
        pixels[x][y] = LOW;
      }else{
        pixels[x][y] = HIGH;
      }
      bitMask = bitMask << 1;
    }
  }

  ptrChar++;
  if(ptrChar>=strLen){
    ptrChar = 0;
  }

}

void refreshScreen() {
  // iterate over the rows (anodes):
  for (int thisRow = 0; thisRow < 8; thisRow++) {
    // take the row pin (anode) high:
    digitalWrite(row[thisRow], HIGH);
    // iterate over the cols (cathodes):
    for (int thisCol = 0; thisCol < 8; thisCol++) {
      // get the state of the current pixel;
      int thisPixel = pixels[thisRow][thisCol];
      // when the row is HIGH and the col is LOW,
      // the LED where they meet turns on:
      digitalWrite(col[thisCol], thisPixel);
      // turn the pixel off:
      if (thisPixel == LOW) {
        digitalWrite(col[thisCol], HIGH);
      }
    }
    // take the row pin low to turn off the whole row:
    digitalWrite(row[thisRow], LOW);
  }
}

Wednesday, August 27, 2014

Arduino example: Self adjust analogRead() to read Photoresistor

This example read analog input of Photoresistor, then turn on 8*8 LED Matrix accordingly.

- It self adjust by checking the maximun and minimum of analog input, then determine the level of light.
- If analog input is less than rejectMin or greater than rejectMax, it will be reject. It's assumed invalid due to bad contact of the breadboard.

Connection:
The resister connect between the photoresistor and GND is 10K ohm.


Program code:
/*
 *  Read Analog I/P from Photoresistor (Analog 0)
 *  and set LED Matrix accordingly
 *  http://arduino-er.blogspot.com/
 */

int PhotoResPin = 0;
int photoResVal = 0;
int photoResMax = 0x00;
int photoResMin = 0x3FF;
int level1, level2, level3, level4;
int level = 0;
const int levelMax = 4;
const int levelMin = 0;
const int NumOfLevel = 5;

const int rejectMin = 0x030;
const int rejectMax = 0x3CF;

// 2-dimensional array of row pin numbers:
const int row[8] = {
  2, 7, 19, 5, 13, 18, 12, 16
};

// 2-dimensional array of column pin numbers:
const int col[8] = {
  6, 11, 10, 3, 17, 4, 8, 9
};

// 2-dimensional array of pixels:
int pixels[8][8];

int count = 1000;

char str[] = "EDCBA";
int strLen = sizeof(str);
int ptrChar = 0;


typedef bool charMapType[8][8];

const charMapType charDummy = {
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0}
};

const charMapType charMin = {
  {1, 1, 1, 1, 1, 1, 1, 1},
  {1, 1, 1, 1, 1, 1, 1, 1},
  {1, 1, 1, 1, 1, 1, 1, 1},
  {1, 1, 1, 1, 1, 1, 1, 1},
  {1, 1, 1, 1, 1, 1, 1, 1},
  {1, 1, 1, 1, 1, 1, 1, 1},
  {1, 1, 1, 1, 1, 1, 1, 1},
  {1, 1, 1, 1, 1, 1, 1, 1}
};

const charMapType char1 = {
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 1, 1, 1, 1, 1, 1, 0},
  {0, 1, 1, 1, 1, 1, 1, 0},
  {0, 1, 1, 1, 1, 1, 1, 0},
  {0, 1, 1, 1, 1, 1, 1, 0},
  {0, 1, 1, 1, 1, 1, 1, 0},
  {0, 1, 1, 1, 1, 1, 1, 0},
  {0, 0, 0, 0, 0, 0, 0, 0}
};

const charMapType char2 = {
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 1, 1, 1, 1, 0, 0},
  {0, 0, 1, 1, 1, 1, 0, 0},
  {0, 0, 1, 1, 1, 1, 0, 0},
  {0, 0, 1, 1, 1, 1, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0}
};

const charMapType char3 = {
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 1, 1, 0, 0, 0},
  {0, 0, 0, 1, 1, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0}
};

const charMapType charMax = {
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 1, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0}
};

const charMapType *charMap[5] = {&charMin, &char1, &char2, &char3, &charMax};

void setup() {
  
  Serial.begin(9600);
  
  // initialize the I/O pins as outputs
  // iterate over the pins:
  for (int thisPin = 0; thisPin < 8; thisPin++) {
    // initialize the output pins:
    pinMode(col[thisPin], OUTPUT);
    pinMode(row[thisPin], OUTPUT);
    // take the col pins (i.e. the cathodes) high to ensure that
    // the LEDS are off:
    digitalWrite(col[thisPin], HIGH);
  }

  
  //setupScreen();
  setupChar();

}

void loop() {

  // draw the screen:
  refreshScreen();

  readPhotoRes();

}

void readPhotoRes(){
  
  int prvLevel = level;
  
  //read photoresistor from analog input
  photoResVal = analogRead(PhotoResPin);
  //Serial.println(photoResVal);

  if(photoResVal < rejectMin) return;  //assume invalid
  if(photoResVal > rejectMax) return;  //assume invalid
  
  if(photoResVal > photoResMax){
    photoResMax = photoResVal;
    adjLevel();
    level = levelMax;
  }else if(photoResVal < photoResMin){
    photoResMin = photoResVal;
    adjLevel();
    level = levelMin;
  }else{
    
    //check valid of photoResMax & photoResMin
    if(photoResMax > photoResMin){
      if(photoResVal < level1){
        level = 0;
      }else if(photoResVal < level2){
        level = 1;
      }else if(photoResVal < level3){
        level = 2;
      }else if(photoResVal < level4){
        level = 3;
      }else{
        level = levelMax;
      }
    }
  }
  
  if(prvLevel != level){
    setupChar();
  }
}

void adjLevel(){
  if(photoResMax > photoResMin){
    int div = (photoResMax - photoResMin)/NumOfLevel;
    level1 = photoResMin + div;
    level2 = level1 + div;
    level3 = level2 + div;
    level4 = level3 + div;
  }
}

void setupChar(){

  const charMapType *cMap = charMap[level];

  for (int x = 0; x < 8; x++) {
    for (int y = 0; y < 8; y++) {
      bool v = (*cMap)[x][y];
      
      if(v){
        pixels[x][y] = LOW;
      }else{
        pixels[x][y] = HIGH;
      }
    }
  }

}

void refreshScreen() {
  // iterate over the rows (anodes):
  for (int thisRow = 0; thisRow < 8; thisRow++) {
    // take the row pin (anode) high:
    digitalWrite(row[thisRow], HIGH);
    // iterate over the cols (cathodes):
    for (int thisCol = 0; thisCol < 8; thisCol++) {
      // get the state of the current pixel;
      int thisPixel = pixels[thisRow][thisCol];
      // when the row is HIGH and the col is LOW,
      // the LED where they meet turns on:
      digitalWrite(col[thisCol], thisPixel);
      // turn the pixel off:
      if (thisPixel == LOW) {
        digitalWrite(col[thisCol], HIGH);
      }
    }
    // take the row pin low to turn off the whole row:
    digitalWrite(row[thisRow], LOW);
  }
}

How it work:

In the video, the wrong color of LED is due to recording fps. It's not too significant visually.

Bit mapping for 8*8 LED Matrix

This post show how to map char to bitmap for 8*8 LED Matrix. In the example code, only 5 char 'A'...'E' are implemented. The char in str[] will be displayed character-by-character.



/*
 *  Modify from Row-Column Scanning an 8x8 LED matrix tutorial
 *  http://arduino-er.blogspot.com/
 */


// 2-dimensional array of row pin numbers:
const int row[8] = {
  2, 7, 19, 5, 13, 18, 12, 16
};

// 2-dimensional array of column pin numbers:
const int col[8] = {
  6, 11, 10, 3, 17, 4, 8, 9
};

// 2-dimensional array of pixels:
int pixels[8][8];

int count = 1000;

char str[] = "EDCBA";
int strLen = sizeof(str);
int ptrChar = 0;


typedef bool charMapType[8][8];

const charMapType charDummy = {
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0}
};

const charMapType charA = {
  {0, 0, 0, 1, 1, 0, 0, 0},
  {0, 0, 0, 1, 1, 0, 0, 0},
  {0, 0, 1, 0, 0, 1, 0, 0},
  {0, 0, 1, 0, 0, 1, 0, 0},
  {0, 1, 1, 1, 1, 1, 1, 0},
  {0, 1, 0, 0, 0, 0, 1, 0},
  {1, 1, 0, 0, 0, 0, 1, 1},
  {1, 0, 0, 0, 0, 0, 0, 1}
};

const charMapType charB = {
  {1, 1, 1, 1, 1, 1, 0, 0},
  {0, 1, 0, 0, 0, 0, 1, 0},
  {0, 1, 0, 0, 0, 0, 0, 1},
  {0, 1, 1, 1, 1, 1, 1, 0},
  {0, 1, 0, 0, 0, 0, 0, 1},
  {0, 1, 0, 0, 0, 0, 0, 1},
  {0, 1, 0, 0, 0, 0, 1, 0},
  {1, 1, 1, 1, 1, 1, 0, 0}
};

const charMapType charC = {
  {0, 1, 1, 1, 1, 1, 1, 0},
  {1, 0, 0, 0, 0, 0, 0, 1},
  {1, 0, 0, 0, 0, 0, 0, 1},
  {1, 0, 0, 0, 0, 0, 0, 0},
  {1, 0, 0, 0, 0, 0, 0, 0},
  {1, 0, 0, 0, 0, 0, 0, 1},
  {1, 0, 0, 0, 0, 0, 0, 1},
  {0, 1, 1, 1, 1, 1, 1, 0}
};

const charMapType charD = {
  {1, 1, 1, 1, 1, 1, 1, 0},
  {0, 1, 0, 0, 0, 0, 0, 1},
  {0, 1, 0, 0, 0, 0, 0, 1},
  {0, 1, 0, 0, 0, 0, 0, 1},
  {0, 1, 0, 0, 0, 0, 0, 1},
  {0, 1, 0, 0, 0, 0, 0, 1},
  {0, 1, 0, 0, 0, 0, 0, 1},
  {1, 1, 1, 1, 1, 1, 1, 0}
};

const charMapType charE = {
  {1, 1, 1, 1, 1, 1, 1, 1},
  {0, 1, 0, 0, 0, 0, 0, 0},
  {0, 1, 0, 0, 0, 0, 0, 0},
  {0, 1, 1, 1, 1, 1, 1, 0},
  {0, 1, 0, 0, 0, 0, 0, 0},
  {0, 1, 0, 0, 0, 0, 0, 0},
  {0, 1, 0, 0, 0, 0, 0, 0},
  {1, 1, 1, 1, 1, 1, 1, 1}
};


const charMapType *charMap[5] = {&charA, &charB, &charC, &charD, &charE};

void setup() {
  // initialize the I/O pins as outputs
  // iterate over the pins:
  for (int thisPin = 0; thisPin < 8; thisPin++) {
    // initialize the output pins:
    pinMode(col[thisPin], OUTPUT);
    pinMode(row[thisPin], OUTPUT);
    // take the col pins (i.e. the cathodes) high to ensure that
    // the LEDS are off:
    digitalWrite(col[thisPin], HIGH);
  }

  
  //setupScreen();
  setupChar();

}

void loop() {

  // draw the screen:
  refreshScreen();
  
  if(count-- == 0){
    count = 1000;
    setupChar();
  }

}

void setupChar(){
  char c = str[ptrChar];
  int offset = c - 'A';
  
  const charMapType *cMap = charMap[offset];
  //charMapType *cMap = &charDummy;
  
  for (int x = 0; x < 8; x++) {
    for (int y = 0; y < 8; y++) {
      bool v = (*cMap)[x][y];
      
      if(v){
        pixels[x][y] = LOW;
      }else{
        pixels[x][y] = HIGH;
      }
    }
  }
  
  ptrChar++;
  if(ptrChar>=strLen-1){
    ptrChar = 0;
  }

}

void refreshScreen() {
  // iterate over the rows (anodes):
  for (int thisRow = 0; thisRow < 8; thisRow++) {
    // take the row pin (anode) high:
    digitalWrite(row[thisRow], HIGH);
    // iterate over the cols (cathodes):
    for (int thisCol = 0; thisCol < 8; thisCol++) {
      // get the state of the current pixel;
      int thisPixel = pixels[thisRow][thisCol];
      // when the row is HIGH and the col is LOW,
      // the LED where they meet turns on:
      digitalWrite(col[thisCol], thisPixel);
      // turn the pixel off:
      if (thisPixel == LOW) {
        digitalWrite(col[thisCol], HIGH);
      }
    }
    // take the row pin low to turn off the whole row:
    digitalWrite(row[thisRow], LOW);
  }
}

Tuesday, August 26, 2014

Walking bit on 8*8 LED Matrix, with Arduino Uno

Last post have a 8*8 LED Matrix, work with Arduino Uno.

It's another test program to turn ON/OFF a walking bit on 8*8 LED Matrix, to clarify all LED work as expect.



/*
 *  Modify from Row-Column Scanning an 8x8 LED matrix tutorial
 *  http://arduino-er.blogspot.com/
 */
/*
  Row-Column Scanning an 8x8 LED matrix with X-Y input

 This example controls an 8x8 LED matrix using two analog inputs

 created 27 May 2009
 modified 30 Aug 2011
 by Tom Igoe

 This example works for the Lumex  LDM-24488NI Matrix. See
 http://sigma.octopart.com/140413/datasheet/Lumex-LDM-24488NI.pdf
 for the pin connections

 For other LED cathode column matrixes, you should only need to change
 the pin numbers in the row[] and column[] arrays

 rows are the anodes
 cols are the cathodes
 ---------

 Pin numbers:
 Matrix:
 * Digital pins 2 through 13,
 * analog pins 2 through 5 used as digital 16 through 19
 Potentiometers:
 * center pins are attached to analog pins 0 and 1, respectively
 * side pins attached to +5V and ground, respectively.

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/RowColumnScanning

 see also http://www.tigoe.net/pcomp/code/category/arduinowiring/514 for more
 */


// 2-dimensional array of row pin numbers:
const int row[8] = {
  2, 7, 19, 5, 13, 18, 12, 16
};

// 2-dimensional array of column pin numbers:
const int col[8] = {
  6, 11, 10, 3, 17, 4, 8, 9
};

// 2-dimensional array of pixels:
int pixels[8][8];

int posX = 7;
int posY = 7;
int count = 30;
bool bg = false;

void setup() {
  // initialize the I/O pins as outputs
  // iterate over the pins:
  for (int thisPin = 0; thisPin < 8; thisPin++) {
    // initialize the output pins:
    pinMode(col[thisPin], OUTPUT);
    pinMode(row[thisPin], OUTPUT);
    // take the col pins (i.e. the cathodes) high to ensure that
    // the LEDS are off:
    digitalWrite(col[thisPin], HIGH);
  }

  setupScreen();

}

void loop() {

  // draw the screen:
  refreshScreen();
  
  if(count-- == 0){
    count = 500;
    if(posX--==0){
      posX = 7;
      if(posY--==0){
        posY = 7;
        bg = !bg;
      }
    }
    setupScreen();

  }
}

void setupScreen(){
  if(bg){
    //ON all others
    for (int x = 0; x < 8; x++) {
      for (int y = 0; y < 8; y++) {
        pixels[x][y] = LOW;
      }
    }
    
    //OFF current pos
    pixels[posX][posY] = HIGH;
  }else{
    //OFF all others
    for (int x = 0; x < 8; x++) {
      for (int y = 0; y < 8; y++) {
        pixels[x][y] = HIGH;
      }
    }
    
    //ON current pos
    pixels[posX][posY] = LOW;
  }
}

void refreshScreen() {
  // iterate over the rows (anodes):
  for (int thisRow = 0; thisRow < 8; thisRow++) {
    // take the row pin (anode) high:
    digitalWrite(row[thisRow], HIGH);
    // iterate over the cols (cathodes):
    for (int thisCol = 0; thisCol < 8; thisCol++) {
      // get the state of the current pixel;
      int thisPixel = pixels[thisRow][thisCol];
      // when the row is HIGH and the col is LOW,
      // the LED where they meet turns on:
      digitalWrite(col[thisCol], thisPixel);
      // turn the pixel off:
      if (thisPixel == LOW) {
        digitalWrite(col[thisCol], HIGH);
      }
    }
    // take the row pin low to turn off the whole row:
    digitalWrite(row[thisRow], LOW);
  }
}

Test 8*8 LED Matrix with Arduino Uno R3

Just purchased a Arduino Start Kit with Arduino Uno R3, and some components. It's the first test for the 8*8 LED Matrix.


Basically it follow the tutorial of Row-columm Scanning to control an 8x8 LED Matrix, can be open in in Arduino IDE (1.5.7 in my case), File -> Examples -> 07.Display -> RowColumnScanning.


The connection follow the diagram:


To make it simple, I remove the two potentiometers, and ignore readSensors() in the code.

8 pcs of 220 ohm resistors are added  to limit the current, to protect my board.

The 8*8 LED Matrix marked 1588BS, it should be the part number or model number. Actually I cannot find any marking to recognize the pin 1. I place it by chance.

To turn on any spot, set it low in the code:

  pixels[x][y] = LOW;

Next:
- Implement walking bit to test all bit ON/OFF.

Arduino IDE on Raspberry Pi

To install Arduino IDE on Raspberry Pi, enter the command:

$ sudo apt-get install arduino

After installed, run it with command:

$ arduino

This video show how to, and also show how Raspberry Pi connected Arduino Uno run.



Cross post with Hello Raspberry Pi.

Arduino IDE error - avrdude: ser_open(): can't open device "/dev/ttyACM0": Permission denied

If you run Arduino IDE on Ubuntu (Arduino 1.5.7 and Ubuntu 14.04 in my case), most possibly you cannot upload to Arduino board, caused by the error of:

avrdude: ser_open(): can't open device "/dev/ttyACM0": Permission denied
ioctl("TIOCMGET"): Inappropriate ioctl for device

To fix it, enter the command:
$ sudo usermod -a -G dialout <username>
$ sudo chmod a+rw /dev/ttyACM0

Where <username> is your user name in Ubuntu, /dev/ttyACM0 is the detected device of your Arduino board.

Check the video:

Sunday, July 13, 2014

Intel GALILEO Microcontroller board

Intel GALILEO Single ATX DDR2 1066 Microcontroller Motherboard GALILEO1.Y

  • Galileo is designed to support shields that operate at either 3.3V or 5V.
  • The core operating voltage of Galileo is3.3V. However, a jumper on the board enables voltage translation to 5V at the I/O pins.
  • This provides support for 5V Uno shields and is the default behavior.
  • Galileo is a microcontroller board based on the Intel® Quark SoC X1000 Application Processor, a 32-bit Intel Pentium®-class system on a chip (SoC).
  • PC industry standard I/O ports and features to expand native usage and capabilities beyond the Arduino shield ecosystem
  • A full sized mini-PCI Express slot, 100Mb Ethernet port, Micro-SD slot, RS-232 serial port, USB Host port, USB Client Port, and 8 MByte NOR flash come standard on the board.

Saturday, July 12, 2014

Intel Galileo lab video playlist



Video include:

  1. Galileo as an Arduino compatible board
  2. Galileo as a linux server
  3. access GPIO from linux
  4. LedSensor in Arduino sketch
  5. LedSensor in shell
  6. LedSensor in C
  7. NodeJS
  8. Servo Motors


Friday, July 11, 2014

Beginning NFC with PhoneGap and Arduino - O'Reilly Webcast



Beginning NFC with PhoneGap and Arduino - O'Reilly Webcast

Originally recorded April 29, 2014. Don Coleman, Tom Igoe, and Brian Jepson (authors of Beginning NFC ) will introduce you to Near Field Communication using Android phones, Arduino, and NFC readers for computers and Arduino. Learn how information on NFC tags is stored and retrieved, how to write applications on Arduino and Android to read and write tags, and how to integrate NFC into larger projects.

Two demos in this session will feature :
  • Reading a tag with an Android PhoneGap application
  • Writing to a tag from Arduino
  • And when both are done, we'll be able to show you how an Android device can read the tag you wrote from Arduino and take an action based on the data you stored.

Saturday, July 5, 2014

duino, control Arduino with Node.js

duino is a framework for working with Arduinos in node.js. Here show how to (with little bit modification) make it run on Ubuntu, to control the LED of Arduino Due using Node.js.

- Connect Arduino Due to your host PC with USB cable.

- In Arduino Due board -

Create a new sketch, copy the source code of du.ino here, https://github.com/ecto/duino/blob/master/src/du.ino.


You will be complained with error of 'int index' redeclared as different kind of symbol. To fix it, rename variable index, for example idx.

#include <Servo.h>


bool debug = false;

int idx = 0;

char messageBuffer[12];
char cmd[3];
char pin[3];
char val[4];
char aux[4];

Servo servo;

void setup() {
  Serial.begin(115200);
}

void loop() {
  while(Serial.available() > 0) {
    char x = Serial.read();
    if (x == '!') idx = 0;      // start
    else if (x == '.') process(); // end
    else messageBuffer[idx++] = x;
  }
}

/*
 * Deal with a full message and determine function to call
 */
void process() {
  idx = 0;

  strncpy(cmd, messageBuffer, 2);
  cmd[2] = '\0';
  strncpy(pin, messageBuffer + 2, 2);
  pin[2] = '\0';

  if (atoi(cmd) > 90) {
    strncpy(val, messageBuffer + 4, 2);
    val[2] = '\0';
    strncpy(aux, messageBuffer + 6, 3);
    aux[3] = '\0';
  } else {
    strncpy(val, messageBuffer + 4, 3);
    val[3] = '\0';
    strncpy(aux, messageBuffer + 7, 3);
    aux[3] = '\0';
  }

  if (debug) {
    Serial.println(messageBuffer);
  }
  int cmdid = atoi(cmd);

  // Serial.println(cmd);
  // Serial.println(pin);
  // Serial.println(val);
  // Serial.println(aux);

  switch(cmdid) {
    case 0:  sm(pin,val);              break;
    case 1:  dw(pin,val);              break;
    case 2:  dr(pin,val);              break;
    case 3:  aw(pin,val);              break;
    case 4:  ar(pin,val);              break;
    case 97: handlePing(pin,val,aux);  break;
    case 98: handleServo(pin,val,aux); break;
    case 99: toggleDebug(val);         break;
    default:                           break;
  }
}

/*
 * Toggle debug mode
 */
void toggleDebug(char *val) {
  if (atoi(val) == 0) {
    debug = false;
    Serial.println("goodbye");
  } else {
    debug = true;
    Serial.println("hello");
  }
}

/*
 * Set pin mode
 */
void sm(char *pin, char *val) {
  if (debug) Serial.println("sm");
  int p = getPin(pin);
  if(p == -1) { if(debug) Serial.println("badpin"); return; }
  if (atoi(val) == 0) {
    pinMode(p, OUTPUT);
  } else {
    pinMode(p, INPUT);
  }
}

/*
 * Digital write
 */
void dw(char *pin, char *val) {
  if (debug) Serial.println("dw");
  int p = getPin(pin);
  if(p == -1) { if(debug) Serial.println("badpin"); return; }
  pinMode(p, OUTPUT);
  if (atoi(val) == 0) {
    digitalWrite(p, LOW);
  } else {
    digitalWrite(p, HIGH);
  }
}

/*
 * Digital read
 */
void dr(char *pin, char *val) {
  if (debug) Serial.println("dr");
  int p = getPin(pin);
  if(p == -1) { if(debug) Serial.println("badpin"); return; }
  pinMode(p, INPUT);
  int oraw = digitalRead(p);
  char m[7];
  sprintf(m, "%02d::%02d", p,oraw);
  Serial.println(m);
}

/*
 * Analog read
 */
void ar(char *pin, char *val) {
  if(debug) Serial.println("ar");
  int p = getPin(pin);
  if(p == -1) { if(debug) Serial.println("badpin"); return; }
  pinMode(p, INPUT); // don't want to sw
  int rval = analogRead(p);
  char m[8];
  sprintf(m, "%s::%03d", pin, rval);
  Serial.println(m);
}

void aw(char *pin, char *val) {
  if(debug) Serial.println("aw");
  int p = getPin(pin);
  pinMode(p, OUTPUT);
  if(p == -1) { if(debug) Serial.println("badpin"); return; }
  analogWrite(p,atoi(val));
}

int getPin(char *pin) { //Converts to A0-A5, and returns -1 on error
  int ret = -1;
  if(pin[0] == 'A' || pin[0] == 'a') {
    switch(pin[1]) {
      case '0':  ret = A0; break;
      case '1':  ret = A1; break;
      case '2':  ret = A2; break;
      case '3':  ret = A3; break;
      case '4':  ret = A4; break;
      case '5':  ret = A5; break;
      default:             break;
    }
  } else {
    ret = atoi(pin);
    if(ret == 0 && (pin[0] != '0' || pin[1] != '0')) {
      ret = -1;
    }
  }
  return ret;
}

/*
 * Handle Ping commands
 * fire, read
 */
void handlePing(char *pin, char *val, char *aux) {
  if (debug) Serial.println("ss");
  int p = getPin(pin);

  if(p == -1) { if(debug) Serial.println("badpin"); return; }
  Serial.println("got signal");

  // 01(1) Fire and Read
  if (atoi(val) == 1) {
    char m[16];

    pinMode(p, OUTPUT);
    digitalWrite(p, LOW);
    delayMicroseconds(2);
    digitalWrite(p, HIGH);
    delayMicroseconds(5);
    digitalWrite(p, LOW);

    Serial.println("ping fired");

    pinMode(p, INPUT);
    sprintf(m, "%s::read::%08d", pin, pulseIn(p, HIGH));
    Serial.println(m);

    delay(50);
  }
}

/*
 * Handle Servo commands
 * attach, detach, write, read, writeMicroseconds, attached
 */
void handleServo(char *pin, char *val, char *aux) {
  if (debug) Serial.println("ss");
  int p = getPin(pin);
  if(p == -1) { if(debug) Serial.println("badpin"); return; }
  Serial.println("signal: servo");

  // 00(0) Detach
  if (atoi(val) == 0) {
    servo.detach();
    char m[12];
    sprintf(m, "%s::detached", pin);
    Serial.println(m);

  // 01(1) Attach
  } else if (atoi(val) == 1) {
    // servo.attach(p, 750, 2250);
    servo.attach(p);
    char m[12];
    sprintf(m, "%s::attached", pin);
    Serial.println(m);

  // 02(2) Write
  } else if (atoi(val) == 2) {
    Serial.println("writing to servo");
    Serial.println(atoi(aux));
    // Write to servo
    servo.write(atoi(aux));
    delay(15);

    // TODO: Experiment with microsecond pulses
    // digitalWrite(pin, HIGH);   // start the pulse
    // delayMicroseconds(pulseWidth);  // pulse width
    // digitalWrite(pin, LOW);    // stop the pulse

  // 03(3) Read
  } else if (atoi(val) == 3) {
    Serial.println("reading servo");
    int sval = servo.read();
    char m[13];
    sprintf(m, "%s::read::%03d", pin, sval);
    Serial.println(m);
  }
}

Compile and upload to Arduino Due board.

- In Host PC, running Ubuntu -

Install duino for Node.js, run the command:

$ npm install duino

Create a .js file, testDuino.js. Copy the example code here, https://github.com/ecto/duino#usage.



You will be complained with error of Cannot open /dev/vboxusb.

To make it run on Ubuntu with usb port of ACMxx, modify  arduino.Board to have device: "ACM".

var arduino = require('duino');
var board = new arduino.Board({
  device: "ACM"
});

var led = new arduino.Led({
  board: board,
  pin: 13
});

led.blink();

- Now you can run your node.js code to toggle the LED on Arduino board.

$ node testDuino