Sunday, September 30, 2012

Arduino Mega + URM04 v2.0 + SPI LCD

As I noticed in previous post there is a way to connect your URM04 v2.0 ultrasonic sensor to Arduino without IO expansion shield.
Initial circuit is instable because it is extremely sensitive to any electrical interference due to the fact that it doesn't have appropriate "protection" - even if you just bring your hand too close to the wires (in case if your body is not grounded) circuit functioning will be broken and you will have to reset Arduino.
This issue may be fixed easily by adding several components: line termination resistor, decoupling (bypass) capacitor, pull-up, pull-down and load resistors - to the circuit (refer to URM04 v2.0 wiki page):
"Upgraded" circuit is stable and works great:
I have also connected  128x64 SPI LCD module to display measured distance on its screen.
Provided SPI LCD library does not work with Arduino 1.0 IDE (only with Arduino 0.23 AFAIK), so I've modified it a bit to correct this confusion - LCD12864RSPI.7z.
Coding:
// SPI LCD <--> Arduino:
// SID <-> Digital 9
// CS <-> Digital 8
// SCK <-> Digital 3
// GND <-> GND
// (?) <-->
// VCC <-> 5V
//
// URM04 v2.0 <--> RS485 board:
// + <--> VCC
// A <--> A
// B <--> B
// - <--> GND
//
// RS485 circuit <--> Arduino:
// VCC <--> 5V
// 1 <--> Digital 19 (RX1)
// 2 <--> Digital 2
// 3 <--> Digital 18 (TX1)
// GND <--> GND
//
#include <LCD12864RSPI.h>
//
//#define AR_SIZE( a ) sizeof( a ) / sizeof( a[0] )
//unsigned char wangzhi[]=" www.DFRobot.com ";//
//unsigned char en_char1[]="ST7920 LCD12864 ";//
//unsigned char en_char2[]="Test, Copyright ";//
//unsigned char en_char3[]="by DFRobot ---> ";//
char lol[] ="LOL!            ";
char temp[16];
//
// Pin number to enable XBee expansion board V5
int EN = 2;
//
// Measure distance using the URM04V2 ultrasonic sensor
void measureDistance(byte device) {
  digitalWrite(EN, HIGH);
  // Trigger distance measurement
  uint8_t DScmd[6] = {0x55, 0xaa, device, 0x00, 0x01, 0x00};   
  for(int i = 0; i < 6; i++) {
    Serial1.write(DScmd[i]);
    DScmd[5] += DScmd[i];
  }
  delay(30);
  // Send command to read measured distance 
  uint8_t STcmd[6] = {0x55, 0xaa, device, 0x00, 0x02, 0x00};
  for(int i = 0; i < 6; i++) {
    Serial1.write(STcmd[i]);
    STcmd[5] += STcmd[i];
  }
  delay(3);
}
//
// Return last measured distance by the URM04V2 ultrasonic sensor
// -1 means the last measurement is out of range or unsuccessful
int readDistance() {
  uint8_t data[8];
  digitalWrite(EN, LOW);
  boolean done = false;
  int counter = 0;
  int result = -1;
  while(!done) {
    int bytes = Serial1.available();
    if(bytes == 8) {
      for(int i = 0; i < 8; i++) {
        data[i] = Serial1.read();
      }
      result = (int)data[5] * 256 + (int)data[6];
      done = true;
    }
    else {
      delay(10);
      counter++;
      // If failed to read measured data for 5 times, give up and return -1
      if(counter == 5) {
        done = true;
      }
    }
  }
  return result;
}
//
void setup() {
  LCDA.Initialise();
  delay(100);
  LCDA.DisplayString(0, 0, (unsigned char *)lol, 16);
  delay(1000); 
  pinMode(EN, OUTPUT);
  delay(250);
  Serial.begin(19200);
  delay(250);
  Serial1.begin(19200);
  delay(250);
  digitalWrite(EN, HIGH);
  delay(1000);
}
//
void loop() {
  measureDistance(0x11);
  int distance = readDistance();
  LCDA.CLEAR();
  delay(100);
  memset(lol, ' ', 16);
  sprintf(lol, "%s cm", dtostrf(distance, 0, 0, temp));
  LCDA.DisplayString(0, 0, (unsigned char *)lol, 16);
  delay(1000);
}
Results:

No comments:

Post a Comment