Arduino Mega y ADC TM7709 (solucionado)

Hola a todos.

Aburrido de intentarlo solicito vuestra ayuda.

Tengo este trozo de código relacionado con el conversor TM7709, proporcionado por el vendedor:

//default connection arduino UNO
//DRDY = 11
//ADIO = 12
//SCLK = 13

#define TM7710_DRDY 3
#define TM7710_ADIO 4
#define TM7710_ADIO_OUT() DDRB|=1<<4
#define TM7710_ADIO_IN() DDRB&=~(1<<4)
#define Set_TM7710_SCLK() PORTB|=1<<5
#define Set_TM7710_ADIO() PORTB|=1<<4
#define Clr_TM7710_SCLK() PORTB&=~(1<<5)
#define Clr_TM7710_ADIO() PORTB&=~(1<<4)

Quiero emplearlo con una placa Arduino Mega 2560
Lo hago de este modo;

//DRDY = 9
//ADIO = 10
//SCLK = 11

#define TM7710_DRDY 9
#define TM7710_ADIO 10
#define TM7710_ADIO_OUT() DDRB|=1<<4 / / bit 4 de DDRB a 1. pin10 entrada
#define TM7710_ADIO_IN() DDRB&=~(1<<4) // bit 4 de DDRB a 0. pin10 a cero
#define Set_TM7710_SCLK() PORTB|=1<<5 // bit 5 de portB a 1. pin11=1
#define Set_TM7710_ADIO() PORTB|=1<<4 // bit 4 de portB a 1. pin10=1
#define Clr_TM7710_SCLK() PORTB&=~(1<<5) // bit 5 de portB a 0. pin11=0
#define Clr_TM7710_ADIO() PORTB&=~(1<<4) // bit 4 de portB a 0. pin10=0

Los comentarios son míos. Para aclararme.
Está bien hecha la migración de pines y puertos?

Gracias

Venga hombre, una ayudita. ¿Nadie ha hecho funcionar esta placa con un Arduino Mega2560?

Al menos, ¿alguien me puede aclarar qué significa esta instrucción?

while((PINB&(1<<TM7710_DRDY))==(1<<TM7710_DRDY));

Gracias

Hola.
No tengo ni idea sobre el ADC que mencionas, pero a juzgar por los pines que utiliza (11-MOSI, 12-MISO, y 13-SCK) veo muy probable que comunique mediante SPI, con lo que para el MEGA deberías usar los pines 51-MOSI, 50-MISO, Y 52-SCK). Tal vez cambiando eso, sin modificar el código original te funcione.

Gracias por la respuesta.
El conversor es este: http://www.ledsandchips.com/232?filter_name=adc&filter_category_id=60

En esa misma página se ofrece un código para conectarlo a Arduino UNO. Yo creo que no usa exactamente la biblioteca SPI, sino unas rutinas subrutinas específicas.

El programa ejemplo que ofrece el vendedor del módulo es este: (he puesto en rojo lo que yo creo que constituye la rutina de comunicación entre Arduino y TM7709)
Mi problema es que uso Arduino MEGA y no sé como hacer la migración de pines.

//TM7709 24bit ADC module arduino sketch

//default connection arduino UNO
//DRDY = 11
//ADIO = 12
//SCLK = 13

#define TM7710_DRDY 3
#define TM7710_ADIO 4
#define TM7710_ADIO_OUT() DDRB|=1<<4
#define TM7710_ADIO_IN() DDRB&=~(1<<4)
#define Set_TM7710_SCLK() PORTB|=1<<5
#define Set_TM7710_ADIO() PORTB|=1<<4
#define Clr_TM7710_SCLK() PORTB&=~(1<<5)
#define Clr_TM7710_ADIO() PORTB&=~(1<<4)

unsigned char x[3];
long Result;
float vref=4.89;

void TM7710_start(void)
{
Clr_TM7710_ADIO();
delayMicroseconds(1);
Clr_TM7710_SCLK();
delayMicroseconds(1);
}

void TM7710_stop(void)
{
Clr_TM7710_ADIO();
delayMicroseconds(1);
Set_TM7710_SCLK();
delayMicroseconds(1);
Set_TM7710_ADIO();
delayMicroseconds(1);
}
void TM7710_write(unsigned char dd)
{
unsigned char i;

for(i=8;i>0;i--)
{
if(dd&0x80)
Set_TM7710_ADIO();
else
Clr_TM7710_ADIO();

delayMicroseconds(1);
Set_TM7710_SCLK();
delayMicroseconds(1);
Clr_TM7710_SCLK();
dd<<=1;
}
}

unsigned char TM7710_read(void)
{
unsigned char data=0,i;

for(i=0;i<8;i++)
{
Set_TM7710_SCLK();

data=data<<1;
if((PINB&(1<<TM7710_ADIO))==(1<<TM7710_ADIO))
{
data=data+1;
}
delayMicroseconds(1);
Clr_TM7710_SCLK();
delayMicroseconds(1);
}
return data;
}
void TM7710_Init()
{
TM7710_ADIO_OUT();
delay(100);
TM7710_stop();
TM7710_start();
TM7710_write(0xBF);
TM7710_write(0x20); //Gain=128
//TM7710_write(0x00); //Gain=16
TM7710_stop();
}
void setup()
{
DDRB|=1<<5 ;
delay(1000);
Serial.begin(57600);
Serial.println("TM7709 24bit ADC Module");
TM7710_Init();
}

void loop()
{
while((PINB&(1<<TM7710_DRDY))==(1<<TM7710_DRDY));
TM7710_start();
TM7710_write(0x7F);
TM7710_ADIO_IN();
for(unsigned char j=0;j<3;j++)
{
x[j]=TM7710_read();
}
TM7710_ADIO_OUT();
TM7710_stop();
Result=x[0];
Result = Result * 256;
Result = Result + x[1];
Result = Result * 256;
Result = Result + x[2];
Result = Result - 6912000;

double volt = Result * vref /16 / 6912000;
printFloat(volt,6);
Serial.println(" V ");

}

void printFloat(float value, int places) {
// this is used to cast digits
int digit;
float tens = 0.1;
int tenscount = 0;
int i;
float tempfloat = value;

// if value is negative, set tempfloat to the abs value

// make sure we round properly. this could use pow from
//<math.h>, but doesn't seem worth the import
// if this rounding step isn't here, the value 54.321 prints as

// calculate rounding term d: 0.5/pow(10,places)
float d = 0.5;
if (value < 0)
d *= -1.0;
// divide by ten for each decimal place
for (i = 0; i < places; i++)
d/= 10.0;
// this small addition, combined with truncation will round our

tempfloat += d;

if (value < 0)
tempfloat *= -1.0;
while ((tens * 10.0) <= tempfloat) {
tens *= 10.0;
tenscount += 1;
}

// write out the negative if needed
if (value < 0)
Serial.print('-');

if (tenscount == 0)
Serial.print(0, DEC);

for (i=0; i< tenscount; i++) {
digit = (int) (tempfloat/tens);
Serial.print(digit, DEC);
tempfloat = tempfloat - ((float)digit * tens);
tens /= 10.0;
}

// if no places after decimal, stop now and return
if (places <= 0)
return;

// otherwise, write the point and continue on
Serial.print('.');

for (i = 0; i < places; i++) {
tempfloat *= 10.0;
digit = (int) tempfloat;
Serial.print(digit,DEC);
// once written, subtract off that digit
tempfloat = tempfloat - (float) digit;
}

}

Efectivamente, parece que a pesar de usar los pines del SPI en el UNO, la lectura y escritura es totalmente por software, así que puedes usar cualquier grupo de pines digitales.

Paso a explicarte un poco a ver si te aclaro o te lío más.

Si echas un vistazo al código, verás que los tres pines en el UNO corresponden al PORTB. Si miras el pinout del MEGA verás que uno de los pines que pretendes usar, el pin9, está en PORTH. Para no complicar mucho la cosa, y seguir usando PORTB, te propongo que uses por ejemplo los pines 10 (PORTB4), 11 (PORTB5), y 12 (PORTB6).

Entonces modificamos los #defines (espero no haberme equivocado):

//TM7709 24bit ADC module arduino sketch

//Conexión Arduino MEGA
//DRDY = 10 = PORTB4
//ADIO = 11 = PORTB5
//SCLK = 12 = PORTB6

#define TM7710_DRDY 4
#define TM7710_ADIO 5
#define TM7710_ADIO_OUT() DDRB|=1<<5
#define TM7710_ADIO_IN() DDRB&=~(1<<5)
#define Set_TM7710_SCLK() PORTB|=1<<6
#define Set_TM7710_ADIO() PORTB|=1<<5
#define Clr_TM7710_SCLK() PORTB&=~(1<<6)
#define Clr_TM7710_ADIO() PORTB&=~(1<<5)

Si te fijas un poco, en todos los defines la letra mágica (B) es la del puerto al que pertenece el pin, y el número "mágico" es el número de pin dentro del puerto. Ese número siempre estará comprendido entre 0 y 7, así que en tu primer intento, los
#define TM7710_DRDY 9
#define TM7710_ADIO 10
son en principio una "aberración" ;).
Saludos.

Muchas gracias, noter.

Ahora lo veo claro. La verdad es que nunca había tratado un pin haciendo referencia a su puerto y a la posición del bit, supongo que se hace por cuestión de rapidez.

Muchas gracias nuevamente

Finalmente he conseguido que funciones con el siguiente programa, por si le puede servir a alguien.

Arduino mega2560 y TM7709 conectados como sigue:

pin Mega2560 pin TM7709
50 DIO
51 DRDY
52 SCK

#define TM7710_DRDY 2
#define TM7710_ADIO 3
#define TM7710_ADIO_OUT() DDRB|=1<<3
#define TM7710_ADIO_IN() DDRB&=~(1<<3)
#define Set_TM7710_SCLK() PORTB|=1<<1
#define Set_TM7710_ADIO() PORTB|=1<<3
#define Clr_TM7710_SCLK() PORTB&=~(1<<1)
#define Clr_TM7710_ADIO() PORTB&=~(1<<3)

unsigned char x[3];
long data;
float vref=5;

void setup() {
DDRB|=1<<1 ; //SCLK COMO SALIDA
delay(1000);
Serial.begin(9600);// set baudrate for PC or serialmonitor the same!
TM7710_Init();
}

void loop(){
while((PINB&(1<<TM7710_DRDY))==(1<<TM7710_DRDY)); //espera a que drdy esté a cero
TM7710_start();
TM7710_write(0x7F);
TM7710_ADIO_IN();
for(unsigned char j=0;j<3;j++)
{
x[j]=TM7710_read();
}

TM7710_ADIO_OUT();
TM7710_stop();

data=x[0];

data = data * 256; //unir los 3 bytes
data = data + x[1];
data = data * 256;
data = data + x[2];
data = data - 6912000;

double mvolt = data * vref /16/691.200;

Serial.println (mvolt,5); //milivoltios

} //end del loop

void TM7710_Init(){
TM7710_ADIO_OUT();
delay(100);
TM7710_stop();
TM7710_start();
TM7710_write(0xBF);
// TM7710_write(0x20); //Gain=128
TM7710_write(0x00); //Gain=16
TM7710_stop();
}

void TM7710_start(void) {
Clr_TM7710_ADIO();
delayMicroseconds(1);
Clr_TM7710_SCLK();
delayMicroseconds(1);
}

void TM7710_stop(void) {
Clr_TM7710_ADIO();
delayMicroseconds(1);
Set_TM7710_SCLK();
delayMicroseconds(1);
Set_TM7710_ADIO();
delayMicroseconds(1);
}

void TM7710_write(unsigned char dd)
{
unsigned char i;

for(i=8;i>0;i--)
{
if(dd&0x80)
Set_TM7710_ADIO();
else
Clr_TM7710_ADIO();

delayMicroseconds(1);
Set_TM7710_SCLK();
delayMicroseconds(1);
Clr_TM7710_SCLK();
dd<<=1;
}
}

unsigned char TM7710_read(void){
unsigned char data=0,i;

for(i=0;i<8;i++)
{
Set_TM7710_SCLK();

data=data<<1;
if((PINB&(1<<TM7710_ADIO))==(1<<TM7710_ADIO))
{
data=data+1;
}
delayMicroseconds(1);
Clr_TM7710_SCLK();
delayMicroseconds(1);
}
return data;
}

Me alegro de que lo solucionaras. ¿Has probado a cambiar la configuración para utilizar otros pines, e incluso otro puerto, por si necesitaras dejar el SPI libre en algún proyecto?
Sería conveniente que editaras el asunto del hilo, añadiendo[Solucionado].
Saludos.