Control the Microchip MCP4922-E/P Digital to Analog Converter using an Arduino board.
I've been using the microchip DAC to output a +/-5V output. I used the Arduino MEGA2560 to write to the SPI bus and it worked great. The code is as follows:
//pin# Pin Name Mapped Pin Name
//19 PB0 ( SS/PCINT0 ) Digital pin 53 (SS)
//20 PB1 ( SCK/PCINT1 ) Digital pin 52 (SCK)
//21 PB2 ( MOSI/PCINT2 ) Digital pin 51 (MOSI)
//22 PB3 ( MISO/PCINT3 ) Digital pin 50 (MISO)
////////////////////////////////////////////////////////////////////////////////////////////////////
//Microchip MCP4922-E/P
//Pin No. Symbol Function
//1 VDD Supply Voltage Input (2.7V to 5.5V)
//3 CS Chip Select Input
//4 SCK Serial Clock Input
//5 SDI Serial Data Input
//8 LDAC Synchronization Input. This pin is used to transfer DAC settings (Input Registers)
// to the output registers (VOUT)
//9 SHDN Hardware Shutdown Input
//10 VOUTB DACB Output
//11 VREFB DACB Reference Voltage Input (VSS to VDD)
//12 VSS Ground reference point for all circuitry on the device
//13 VREFA DACA Reference Voltage Input (VSS to VDD)
//14 VOUTA DACA Output
////////////////////////////////////////////////////////////////////////////////////////////////////
// inslude the SPI library:
#include <SPI.h>
// set pin 10 and 11 as the chip select
const int nCS0 = 8;
const int nCS1 = 11;
const int nLDAC = 12;
const int nSHDN = 9;
const int GAINx1 = 1;
const int GAINx2 = 0;
const int Write_to_DACA = 0;
const int Write_to_DACB = 1;
const int BUF = 1;
const int nSHDown = 1;
// analog potentiometer joystick
int joystickBlue = A1;
int AnalogValue = 0; //to store the value here
void setup() {
pinMode(nCS0, OUTPUT);
pinMode(nCS1, OUTPUT);
pinMode(nLDAC, OUTPUT);
pinMode(nSHDN, OUTPUT);
// Set shutdown pin to high
digitalWrite(nSHDN, HIGH);
// initialize the nLDAC to high
pinMode(nLDAC, HIGH);
// initialize SPI:
SPI.begin();
SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
Serial.begin(115200);
}
void loop() {
// analog values
AnalogValue = analogRead(joystickBlue);
// Write to DA
String myBinString = String(Write_to_DACA) + String(BUF) + String(GAINx2)+ String(nSHDown) + ConvertInt2Bin12(3000);
// Write to DB
String myBinStringB =String(Write_to_DACB) + String(BUF) + String(GAINx2)+ String(nSHDown) + ConvertInt2Bin12(2048);
Serial.println(myBinString);
int tempA = ConvertBin2Dec(myBinString);
Serial.println(tempA, HEX);
Serial.println(" ");
Serial.println(myBinStringB);
int tempB = ConvertBin2Dec(myBinStringB);
Serial.println(tempB, HEX);
Serial.println(" ");
delay(500);
digitalWrite(nCS0, LOW); //Enable the chip U4 for X output
SPI.transfer16(tempA);
digitalWrite(nCS0, HIGH);
digitalWrite(nCS0, LOW);
SPI.transfer16(tempB);
digitalWrite(nCS0, HIGH);
Latch_DAC_Input();
}
void DAC_Write(int address, int value, int CSNum){
// Do the chip select value
if (CSNum == 0) {
digitalWrite(nCS0, LOW);
}else if (CSNum == 1) {
digitalWrite(nCS1, LOW);
}
// send in the address and value via SPI:
SPI.transfer(address);
SPI.transfer(value);
if (CSNum == 0) {
digitalWrite(nCS0, HIGH);
}else if (CSNum == 1) {
digitalWrite(nCS1, HIGH);
}
}
void Latch_DAC_Input(){
//toggle the nLDAC to output voltage
digitalWrite(nLDAC, LOW);
digitalWrite(nLDAC, HIGH);
}
String ConvertInt2Bin12(int Value){
//this sub will convert any integer value to its corresponding 12 bit
String myString = String(Value, BIN);
int lenString = myString.length();
for ( int i=lenString; i<12; ++i){
myString = "0" + myString;
}
return myString;
}
int ConvertBin2Dec(String BinData){
//this sub will convert a 16 bit binary string to its equivalent HEX
int LenString = BinData.length();
double ValueDec = 1;
int DataOut = 0;
for ( int i = 0; i < LenString; i++){
String MyStr =BinData.substring(LenString-i-1, LenString-i);
if (MyStr == "0"){
// add a zero
}else{
//add a 2^i
ValueDec = pow(2,(float)i) + ValueDec;
}
}
DataOut = ValueDec;
return DataOut;
}
Monday, March 7, 2016
Parallax Serial LCD Arduino Subroutines
Parallax Serial LCD
2 rows x 16 characters Non-backlit (#27976)
2 rows x 16 characters Backlit (#27977)
4 rows x 20 characters Backlit (#27979)
http://elmicro.com/files/parallax/seriallcd-v20.pdf
The best way to interface to this Serial LCD is to use the software serial library offered by Arduino environment. Be sure that the following is on your code.
///////////////////////// Libraries ///////////////////////////////
#include <SoftwareSerial.h>
//////////////////////// LCD Variables ///////////////////////////
SoftwareSerial mySerial(10, 11); // RX, TX
Then, write subroutines to initialize the LCD.
void initializeLCD(){
mySerial.begin(19200); //change per LCD
delay(500);
// put your setup code here, to run once:
mySerial.write(12);
delay(5);
}
Subroutines to control the screen
void LCD_clearScreen(){
mySerial.write(12);
delay(10);
}
void Turn_backlight_on_LCD(){
mySerial.write(17);
delay(5);
}
void Turn_backlight_off_LCD(){
mySerial.write(18);
delay(5);
}
void Line_Feed_LCD(){
mySerial.write(12);
delay(5);
}
void Carriage_Return_LCD(){
mySerial.write(13);
delay(5);
}
void Move_Cursor(int line, int pos){
switch (line){
case 0:
mySerial.write(128 + pos);
delay(5);
break;
case 1:
mySerial.write(148 + pos);
delay(5);
break;
case 2:
mySerial.write(168 + pos);
delay(5);
break;
case 3:
mySerial.write(188 + pos);
delay(5);
break;
default:
// do nothing
break;
}
delay(5);
}
To write the a float value onto the LCD, it would work best if it was converted to a string as described below using dtostrf function
void LCD_floatValue(){
int StringLen = 7;
int numVarAfterDec = 3;
static char outstr[15]; // the array to store the results
static float f_val = Lever_Position;
dtostrf(Lever_Position,7, 1, outstr);
Move_Cursor(0,0);
delay(5);
mySerial.print("Value ");
mySerial.println (outstr);
}
2 rows x 16 characters Non-backlit (#27976)
2 rows x 16 characters Backlit (#27977)
4 rows x 20 characters Backlit (#27979)
http://elmicro.com/files/parallax/seriallcd-v20.pdf
The best way to interface to this Serial LCD is to use the software serial library offered by Arduino environment. Be sure that the following is on your code.
///////////////////////// Libraries ///////////////////////////////
#include <SoftwareSerial.h>
//////////////////////// LCD Variables ///////////////////////////
SoftwareSerial mySerial(10, 11); // RX, TX
Then, write subroutines to initialize the LCD.
void initializeLCD(){
mySerial.begin(19200); //change per LCD
delay(500);
// put your setup code here, to run once:
mySerial.write(12);
delay(5);
}
Subroutines to control the screen
void LCD_clearScreen(){
mySerial.write(12);
delay(10);
}
void Turn_backlight_on_LCD(){
mySerial.write(17);
delay(5);
}
void Turn_backlight_off_LCD(){
mySerial.write(18);
delay(5);
}
void Line_Feed_LCD(){
mySerial.write(12);
delay(5);
}
void Carriage_Return_LCD(){
mySerial.write(13);
delay(5);
}
void Move_Cursor(int line, int pos){
switch (line){
case 0:
mySerial.write(128 + pos);
delay(5);
break;
case 1:
mySerial.write(148 + pos);
delay(5);
break;
case 2:
mySerial.write(168 + pos);
delay(5);
break;
case 3:
mySerial.write(188 + pos);
delay(5);
break;
default:
// do nothing
break;
}
delay(5);
}
To write the a float value onto the LCD, it would work best if it was converted to a string as described below using dtostrf function
void LCD_floatValue(){
int StringLen = 7;
int numVarAfterDec = 3;
static char outstr[15]; // the array to store the results
static float f_val = Lever_Position;
dtostrf(Lever_Position,7, 1, outstr);
Move_Cursor(0,0);
delay(5);
mySerial.print("Value ");
mySerial.println (outstr);
}
Labels:
Arduino,
dtostrf,
MEGA2560,
Parallax Code,
Serial LCD
Location:
Pasadena, CA, USA
L298 Motor Driver with Arduino MEGA2560
Arduino MEGA 2560
This is my first blog about the Mega2560. It has become a very useful tool for rapid prototyping and making simple project. When I say simple I mean simple but useful.
I recently connected a DC Motor that required a potentiometer as a sensor and a motor driver (L298).
Arduino, you can buy anywhere nowadays. I usually buy mine from sparkfun $46
(https://www.sparkfun.com/products/11061)
L298 Driver: I also buy this from Sparkfun $35
(https://www.sparkfun.com/products/9670)
Connect the motor signals according to the Arduino declarations below:
////////////////////////// Motor Driver #1 Signals /////////////////////////////
const int MOT1_EN = 26;
const int MOT1_IN1 = 22;
const int MOT1_IN2 = 24;
const int MOT1_CSA = A4;
const int MOT1_CSB = A5;
const int POT = A0;
Initialize the motor signals before using.
pinMode(MOT1_IN1, OUTPUT);
pinMode(MOT1_IN2, OUTPUT);
pinMode(MOT1_EN, OUTPUT);
pinMode(MOT1_CSA, INPUT);
pinMode(MOT1_CSB, INPUT);
Create subroutine to move the motors Clockwise and counter clock wise.
void Motor1_CC(){
digitalWrite(MOT1_EN, HIGH);
delay(1);
digitalWrite(MOT1_IN1, HIGH);
digitalWrite(MOT1_IN2, LOW);
}
void Motor1_CCW(){
digitalWrite(MOT1_EN, HIGH);
delay(1);
digitalWrite(MOT1_IN1, LOW);
digitalWrite(MOT1_IN2, HIGH);
}
Write routines to break and coast motors
void Motor1_FastBrake(){
//this routine will brake the motor A quickly
digitalWrite(MOT1_EN, HIGH);
delay(1);
digitalWrite(MOT1_IN1, LOW);
digitalWrite(MOT1_IN2, LOW);
}
void Motor1_Coast(){
//this routine will coast Motor A
digitalWrite(MOT1_EN, LOW);
delay(1);
digitalWrite(MOT1_IN1, LOW); //irrelevent
digitalWrite(MOT1_IN2, LOW); //irrelevent
}
Now we are ready to write our code according to the project requirements. I would read the analog value for the potentiometer and move the motors using the routines as needed.
Enjoy!
Location:
Pasadena, CA, USA
Subscribe to:
Posts (Atom)