Tecnología > Electricidad y Electrónica
Voltímetro digital de precisión con LTC2400
Carlos:
Voltímetro con Arduino basado en el conversor Analógico/Digital de 24 bits LTC2400 de Linear Technology
Carlos:
Programa de Arduino
--- Código: (Arduino) ---/*
TEST PROGRAM:
LTC2400 Sigma-Delta 24bit ADC converter
DATASHEET: http://cds.linear.com/docs/en/datasheet/2400fa.pdf
WEBPAGE: http://www.linear.com/product/LTC2400
ARDUINO -> LTC2400
--------------------
GND -> (4) GND
D2 -> (7) SCK
D3 -> (6) SDO
D4 -> (5) /CS
--------------------
ARDUINO -> I2C-LCD
--------------------
GND -> GND
5V -> VCC
A4 -> SDA
A5 -> SCL
--------------------
Web page: https://www.picuino.com/foro/index.php?topic=9.0
License: GPLv3 http://www.gnu.org/licenses/gpl-3.0.txt
Creation date: 2/05/2015
Revision 09/05/2015:
Added Arduino -> I2C-LCD conexion explanation.
*/
#include <Wire.h> // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
// Setup LCD 16x2 chars
LiquidCrystal_I2C lcd(0x27,16,2);
// ADC Pin definition
const int ADC_SCK = 2; // Serial ClocK
const int ADC_SDO = 3; // Serial Digital Output
const int ADC_CS = 4; // Chip Select
const int sampling_time = 500; // Sampling time in milliseconds
/*
Init LTC2400 signals
*/
void adc_init(void) {
pinMode(ADC_SCK, OUTPUT);
digitalWrite(ADC_SCK, HIGH);
pinMode(ADC_CS, OUTPUT);
digitalWrite(ADC_CS, LOW);
pinMode(ADC_SDO, INPUT);
}
/*
Read 32 raw data bits from LTC2400
*/
unsigned long adc_read32(void) {
unsigned long int count;
digitalWrite(ADC_CS, LOW); // ADC Chip Select
count = 0;
// Read 32 bits from serial ADC
for(char i=32; i; i--) {
count <<= 1;
digitalWrite(ADC_SCK, LOW); // Send Clock Signal
digitalWrite(ADC_SCK, HIGH);
if (digitalRead(ADC_SDO)) {
count |= 1;
}
}
digitalWrite(ADC_SCK, LOW); // Init next conversion
return count;
}
/*
Read voltage from LTC2400
Return 0x80000000 if not conversion available
Return values from negative 0xFF... to positive 0x1F...
*/
long int adc_read(void) {
signed long count;
char stat;
count = adc_read32();
// Get status
stat = count >> 28;
count &= 0x0FFFFFFF;
// Test end of conversion
if (stat & 8) {
return 0x80000000;
}
// Positive Extended Range
if (stat == 3)
count += 0x0FFFFFFF;
// Negative Extended Range
if (stat == 1)
count += 0xF0000000;
return count;
}
/*
Return 1 if ADC End Of Conversion bit is Enable
*/
int adc_eoc(void) {
digitalWrite(ADC_CS, LOW);
return(!digitalRead(ADC_SDO));
}
/******************************************************
MAIN PROGRAM
*****************************************************/
// Init program
unsigned long sample_time;
void setup() {
// Initialize serial communications
Serial.begin(115200);
// Initialize ADC
adc_init();
sample_time = millis() + 200;
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.print("System OK ");
}
// Main Loop
void loop() {
long count;
static float volt1, volt2;
// Wait for next adquisition
if (millis() > sample_time) {
sample_time += sampling_time;
// Read ADC
count = adc_read();
delay(165);
// Convert ADC to voltage
volt1 = volt2;
volt2 = ((float)count) * (5.000000/(256.0*1024.0*1024.0));
count = ((volt2 - volt1)*1000000.0);
// Print voltage to serial port
if (volt2 >= 0) Serial.print(" ");
Serial.print(volt2, 6);
Serial.print("\t");
if (count >= 0) Serial.print(" ");
Serial.println(count);
// Print voltage to LCD
lcd.setCursor(0, 0);
lcd.print("V=");
if (volt2 >= 0)
lcd.print(" ");
lcd.print(volt2, 6);
lcd.print(" ");
// Print voltage difference to LCD second line
lcd.setCursor(0, 1);
char sign;
if (count<0) {
count = -count;
sign = -1;
}
else {
sign = 1;
}
// Right justified number
lcd.print(" ");
if (count<1000000) lcd.print(" ");
if (count<100000) lcd.print(" ");
if (count<10000) lcd.print(" ");
if (count<1000) lcd.print(" ");
if (count<100) lcd.print(" ");
if (count<10) lcd.print(" ");
if (sign == -1)
lcd.print("-");
else
lcd.print(" ");
lcd.print(count);
lcd.print(" ");
}
}
--- Fin del código ---
Carlos:
Componentes utilizados:
* LTC2400 Conversor Analógico/Digital Sigma-Delta de 24 bits
Linear Technology Samples
* ADR4550ARZ Referencia de tensión de precisión de 5v
Samples de Analog Devices
* Conversor I2C - LCD
* Arduino Nano compatible
* Display LCD de 16 columnas x 2 filas
Librerías Arduino:
LiquidCrystal_I2C (copia local)
Carlos:
En este video se puede ver al voltímetro en acción midiendo la salida de tensión de un regulador LM78L05.
En el video, se calienta al regulador para comprobar cómo cambia la tensión de salida con la temperatura.
[youtube]fU3rQj6sFgk[/youtube]
Medida de varias referencias de tensión (más precisas y estables) y de varios reguladores de tensión:
[youtube]ERDTHneD4Ak[/youtube]
Saludos.
Manuel:
Fantástica idea, la de un voltímetro digital con arduino.
Muchas gracias por regalarme el ADC de microchip. Lo he probado nada más llegar a casa, y funciona fantásticamente. Hace unos meses compré en ebay una referencia de voltaje ADR421, de 2.5 voltios, con muy bajo ruido y una precisión inicial de 400ppm que sabía que acabaría usando, así que la incorporé al breadboard. El resultado es este voltímetro/arduino, midiendo la caída de voltaje en un 1N4148:
y la salida por pantalla:
prácticamente los clásicos 0.6 voltios que se esperan en este caso. Basta tocar el diodo para apreciar la variación exponencial del voltaje con la temperatura ;D . También he probado con un diodo de germanio, y con una división de voltaje, para calibrar. Todo perfecto, con muchos decimales.
El código fuente que he usado, bastante crudo todavía, es:
--- Código: (Arduino) ---#include <SPI.h>
/* D13 -> SCK
* D12 -> MISO
* D11 -> MOSI (UNUSED)
* D9 -> SS
*/
#define SCKPIN 13
#define MISOPIN 12
#define MOSIPIN 11
#define SSPIN 9
SPISettings settingsA(100000, MSBFIRST, SPI_MODE3);
void setup() {
pinMode (SSPIN, OUTPUT);
SPI.begin();
Serial.begin(9600);
}
void loop() {
long ret;
double vout;
SPI.beginTransaction(settingsA);
digitalWrite (SSPIN, LOW);
// while(1) {
while (digitalRead(MISOPIN) != LOW); // Wait for ADC ready.
ret = SPI.transfer(0);
ret <<= 8;
ret |= SPI.transfer(0);
ret <<= 8;
ret |= SPI.transfer(0);
delay(1);
digitalWrite (SSPIN, HIGH);
vout = 2.5 * ((double) ret) / (2097152.0);
Serial.println(vout,8);
//}
SPI.endTransaction();
delay(500);
}
--- Fin del código ---
En cuanto tenga tiempo, voy a hacer un programa en python que lea los datos del ADC y los procese con ScyPy, para dar gráficas y demás.
¡Gracias por el chip y por la idea! Si te parece que éste no es lugar correcto para el post, muévelo a otro lado con toda libertad.
Navegación
[#] Página Siguiente
Ir a la versión completa