/*
Arduino UNO sketch for tinyLiDAR Radar, Rev 1.0
This program will control tinyLiDAR and sweep an Analog servo connected to pin 9.
The data will be sent to the Processing Sketch called "tinyLiDAR_Radar_PDE_sketch.pde".
Last Edit: July 19, 2017
Copyright (c) 2017 by Dinesh Bhatia
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see
NOTE: This code requires the "SoftI2CMaster" library to allow the
standard I2C stretch feature to work properly on the UNO. It is not
required for other Arduino types.
** Please install it before running this sketch. **
You can download the library from here:
https://playground.arduino.cc/Main/SoftwareI2CLibrary
References:
https://arduino.stackexchange.com/questions/12718/increase-pwm-bit-resolution
http://howtomechatronics.com/projects/arduino-radar-project/
http://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf
Servo used:
Seeed Part #316010005
Servo Pinout:
Yellow pin = PWM input
Orange pin = +5v
Brown pin = GND
*/
#define SERVO_PIN 9
#define I2C_Address 0x20 // tinyLIDAR default I2C address
#define dwellTime 50 // in milliseconds is optional for the end of servo rotation
#define SDA_PORT PORTC
#define SDA_PIN 4
#define SCL_PORT PORTC
#define SCL_PIN 5
#include
SoftWire Wire = SoftWire();
int start_pulse_width = 530; //pulse width in microseconds for 0deg on servo
int increment = 10; //10us increments = 1deg steps
int end_pulse_width = start_pulse_width + 180*increment; //pulse width in microseconds for 180deg on servo
void setup() {
pinMode(SERVO_PIN, OUTPUT);
Serial.begin(115200);
Wire.begin();
int i = ContinuousMode(); //set tinyLIDAR to fast mode
setupPWM16(); //setup the TC1 timer for 16bit PWM
} //setup
void loop() {
int currentPW = 0;
delay(dwellTime);
for (currentPW = start_pulse_width; currentPW < end_pulse_width; currentPW += increment) {
writeData(currentPW);
} //for currentPW
delay(dwellTime);
for (currentPW = end_pulse_width; currentPW > start_pulse_width; currentPW -= increment) {
writeData(currentPW);
} //for currentPW
} //loop
void Write_I2C(uint8_t address, const char * command1, const char * command2)
{
Wire.beginTransmission(address);
Wire.write(command1);
if (command2 != NULL)
Wire.write(command2);
Wire.endTransmission();
} //Write_I2C
//To read 1 or 2 bytes only
uint16_t Read_I2C(uint8_t address, uint8_t numbytes)
{
uint16_t value = 0;
Wire.requestFrom(address, numbytes);
value = Wire.read();
numbytes--;
if (numbytes) {
value = value << 8;
value |= Wire.read();
} //if numbytes
return value;
} //Read_I2C
uint16_t Read_Distance_C()
{
Write_I2C(I2C_Address, "D", "");
return Read_I2C(I2C_Address, 2);
} //Read_Distance
int ContinuousMode(void)
{
Write_I2C(I2C_Address, "M", "C");
return Read_I2C(I2C_Address, 1);
} //ContinuousMode
void setupPWM16() {
DDRB |= _BV(PB1); // pin 9 OC1A as output
TCCR1A = _BV(COM1A1) // non-inverting PWM
| _BV(WGM11); // mode 14: fast PWM, TOP=ICR1
TCCR1B = _BV(WGM13) | _BV(WGM12)
| _BV(CS11) ; // div by 8 prescaling
ICR1 = 0xffff; // TOP counter value
} //setupPWM16
void writeData(int currentPW)
{
OCR1A = currentPW*2; //write 16bit PWM (0.5us resolution) value to TC1 timer
//map the range to angle in integer degrees
int angle = map(currentPW, start_pulse_width, end_pulse_width, 0, 180);
Serial.print(angle);
Serial.print(F(","));
Serial.print(Read_Distance_C() / 10); //div 10 to convert mm to cm
Serial.println(F("."));
} //writeData