Interfacciamento Max 14521 i2c

Ciao ho appena realizzato una board con l’integrato max 14521, questo integrato è un driver per tubi Elettroluminescenti. Purtroppo non riesco a interfacciarmi con il mio Arduino Unoi R3. E’ la prima volta che utilizzo la libreria Wire senza avere una libreria o esempio precompilato alle spalle. Il mio principale problema è:

  • Come posso scrivere un dato all’interno di un indirizzo? (per ora continua a rispondere errore2)
    per essere precisi ad esempio ho il registro 0x02 e devo scrivere due “1” in B0 e B7. COme glielo dico??
  • Come posso a dare un nome al chip oppure richiamarlo?

Allego il datasheet e riporto il codice beta che ho formulato. Grazie per la pazienza.
Sandro

#include <Wire.h>
int resetPin = 2;
uint16_t max14521_registers[8];
#define FAIL  0
#define SUCCESS  1
#define DEVICE_ID 0x00
#define POWERMODE  0x01
#define EL_FREQ  0x02
#define EL_SHAPE  0x03
#define BOOST_CONVERTER 0x04
#define AUDIO  0x05
#define EL1OUT  0x06
#define EL2OUT  0x07
#define EL3OUT  0x08
#define EL4OUT  0x09
#define MAX14521 0x00 
int SDIO = A4; //SDA/A4 on Arduino
int SCLK = A5; //SCL/A5 on Arduino
byte Address;
byte DATA;

void setup() {                
pinMode(13, OUTPUT);
pinMode(A2,OUTPUT);
pinMode(A4,OUTPUT);
pinMode(A5,OUTPUT);
Serial.begin(57600);
Serial.println();
//CLEAR REGISTER
digitalWrite(resetPin, LOW); //Put Si4703 into reset
delay(1); //Some delays while we allow pins to settle
digitalWrite(resetPin, HIGH); //Bring Si4703 out of reset with SDIO set to low and SEN pulled high with on-board resistor
delay(1); //Allow Si4703 to come out of reset
//
max14521_init;
}
void loop(){
max14521_init();
//define ID
Address=DEVICE_ID;
DATA=1110;
max14521_Write();
//ENABLE
Address=POWERMODE;
DATA=7;
max14521_Write();
//ENABLE
Address=POWERMODE;
DATA=0;
max14521_Write();
//EL_FREQ
Address=EL_FREQ;
DATA=7;
max14521_Write();
 //EL_SHAPE
Address=EL_SHAPE;
DATA=6;
max14521_Write();
//
 //EL_AUDIO
Address=AUDIO;
DATA=6;
max14521_Write();
//

}
void max14521_init(void) {
Serial.println("Initializing I2C and Max14521");
  pinMode(13,OUTPUT);
digitalWrite(13,HIGH);
delay(500);

pinMode(resetPin, OUTPUT);
delay(1);
pinMode(SDIO, OUTPUT); //SDIO is connected to A4 for I2C
digitalWrite(SDIO, LOW); //A low SDIO indicates a 2-wire interface
digitalWrite(13,LOW);
delay(1);
Wire.begin(); //Now that the unit is reset and I2C inteface mode, we need to begin I2C
}
byte max14521_Write (void) {

Wire.beginTransmission(MAX14521);

  Wire.write(Address); //Upper 8 bits
  Wire.write(DATA); //Lower 8 bits


//End this transmission
byte ack = Wire.endTransmission();
if(ack != 0) { //We have a problem! 
  Serial.print("Write Fail:"); //No ACK!
  Serial.println(ack, DEC); //I2C error: 0 = success, 1 = data too long, 2 = rx NACK on address, 3 = rx NACK on data, 4 = other error
  return(FAIL);
}

return(SUCCESS);
}

MAX14521E.zip (572 KB)

soprattutto Paragrafo 6, 7, 11

Ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni
e a leggere il regolamento: Regolamento

Come scritto anche da @pablos:
Il codice devi racchiuderlo nei tag code, vedi sezione 7 del regolamento, spiega bene come fare.
Altrimenti parte del codice può essere visualizzata male o mancare perchè interpretato come attributo del testo stesso.
E da paragrafo 6: "Soprattutto evitate di scrivere gli oggetti usando le LETTERE MAIUSCOLE. Sono sconvenienti da usare e non piacciono ad un sacco di persone perché il maiuscolo significa che si sta urlando."

OK grazie degli accorgimenti è il primo topic. ;D

nessuno riesce a darmi due dritte sull'i2c? :sob:

Sbaglio o tu fai una .beginTransmission usando la costante MAX14521 => 0x00
che vale 0 ? Quello è l'indirizzo del dispositivo, mi pare strano 0
Usa lo sketch i2cscanner che ti dice qual'e' indirizzo del tuo dispositvo (esempio 0x3C)
Penso sia quello il problema infatti ti da errore 2 che è "rx NACK on address" ovvero indirizzo sconosciuto

ok grazie ora provo subito riesci a spiegarmi, dato il registro come faccio a scrivere dentro al bit preciso? e nel momento in cui io scrivo un valore questo è un hex che viene trasformato in binario e riempie il registro o cosa?. Grazie spero la domanda sia comprensibile.

Ti ringrazio per la dritta, ho eseguito il codice dello scan e la risposta è 0x078 che in binario è 1111000 esattamente come riporta il datasheet in base ai collegamenti che ho realizzato. Ho corretto il codice cercando di seguire il data format riportato nel datasheet a pagina17. Ora la risposta del software è continuamente 4(altri errori). Non capisco se questo numero 78 lo devo scrivere come 0x78, 78 o in binario . Ho provato tutti e tre i formati senza risultato :frowning:
Riporto il codice aggiornato.

Grazie per il sostegno…

uff questo software …

#include <Wire.h>
int resetPin = 2;
uint16_t max14521_registers[8];
#define FAIL  0
#define SUCCESS  1
#define DEVICE_ID 0x00
#define POWERMODE  0x01
#define EL_FREQ  0x02
#define EL_SHAPE  0x03
#define BOOST_CONVERTER 0x04
#define AUDIO  0x05
#define EL1OUT  0x06
#define EL2OUT  0x07
#define EL3OUT  0x08
#define EL4OUT  0x09
#define MAX14521 0x00 
int SDIO = A4; //SDA/A4 on Arduino
int SCLK = A5; //SCL/A5 on Arduino
byte Address;
byte DATA;

void setup() {                
  pinMode(13, OUTPUT);
  pinMode(A2,OUTPUT);
  pinMode(A4,OUTPUT);
  pinMode(A5,OUTPUT);
  Serial.begin(57600);
  Serial.println();
  //CLEAR REGISTER
  digitalWrite(resetPin, LOW); //Put Si4703 into reset
  delay(1); //Some delays while we allow pins to settle
  digitalWrite(resetPin, HIGH); //Bring Si4703 out of reset with SDIO set to low and SEN pulled high with on-board resistor
  delay(1); //Allow Si4703 to come out of reset
  //
 max14521_init;
}
void loop(){
  max14521_init();
  //ENABLE
  Address=POWERMODE;
  DATA=7;
  max14521_Write();
  //ENABLE
  Address=POWERMODE;
  DATA=0;
  max14521_Write();
  //EL_FREQ
  Address=EL_FREQ;
  DATA=7;
  max14521_Write();
   //EL_SHAPE
  Address=EL_SHAPE;
  DATA=6;
  max14521_Write();
  //
   //EL_AUDIO
  Address=AUDIO;
  DATA=6;
  max14521_Write();
  //
  
}
void max14521_init(void) {
  Serial.println("Initializing I2C and Max14521");
  pinMode(resetPin, OUTPUT);
  delay(1);
  pinMode(SDIO, OUTPUT); //SDIO is connected to A4 for I2C
  digitalWrite(SDIO, LOW); //A low SDIO indicates a 2-wire interface
  delay(1);
  Wire.begin(); //Now that the unit is reset and I2C inteface mode, we need to begin I2C
}
byte max14521_Write (void) {

    Wire.beginTransmission(MAX14521);
    Wire.write(78);
    pinMode(SDIO, OUTPUT); //SDIO is connected to A4 for I2C
    digitalWrite(SDIO, LOW); //A low SDIO indicates a 2-wire interface
    byte ack = Wire.endTransmission();
    if(ack != 0) { //We have a problem! 
    Serial.print("Write Fail:"); //No ACK!
    Serial.println(ack, DEC); //I2C error: 0 = success, 1 = data too long, 2 = rx NACK on address, 3 = rx NACK on data, 4 = other error
    return(FAIL);
    }
    return(SUCCESS);
    Wire.write(Address); //Upper 8 bits
   
    byte ack1 = Wire.endTransmission();
    if(ack1 != 0) { //We have a problem! 
    Serial.print("Write Fail:"); //No ACK!
    Serial.println(ack, DEC); //I2C error: 0 = success, 1 = data too long, 2 = rx NACK on address, 3 = rx NACK on data, 4 = other error
    return(FAIL);
    }

    return(SUCCESS);
    Wire.write(DATA); //Lower 8 bits
    //End this transmission
    byte ack2 = Wire.endTransmission();
    if(ack2 != 0) { //We have a problem! 
    Serial.print("Write Fail:"); //No ACK!
    Serial.println(ack, DEC); //I2C error: 0 = success, 1 = data too long, 2 = rx NACK on address, 3 = rx NACK on data, 4 = other error
    return(FAIL);
    }
    return(SUCCESS);

}

ho modificato ancora il codice ed ora non ho più messaggi di errore però no si accende nessun canale :frowning:
Riporto il codice modificato.

#include <Wire.h>
int resetPin = 2;
uint16_t max14521_registers[8];
#define FAIL  0
#define SUCCESS  1
#define DEVICE_ID 0x00
#define POWERMODE  0x01
#define EL_FREQ  0x02
#define EL_SHAPE  0x03
#define BOOST_CONVERTER 0x04
#define AUDIO  0x05
#define EL1OUT  0x06
#define EL2OUT  0x07
#define EL3OUT  0x08
#define EL4OUT  0x09
#define MAX14521 0x00 
int SDIO = A4; //SDA/A4 on Arduino
int SCLK = A5; //SCL/A5 on Arduino
byte Address;
byte DATA;

void setup() {                
  pinMode(13, OUTPUT);
  pinMode(A2,OUTPUT);
  pinMode(A4,OUTPUT);
  pinMode(A5,OUTPUT);
  Serial.begin(57600);
  Serial.println();
  //CLEAR REGISTER
  digitalWrite(resetPin, LOW); //Put Si4703 into reset
  delay(1); //Some delays while we allow pins to settle
  digitalWrite(resetPin, HIGH); //Bring Si4703 out of reset with SDIO set to low and SEN pulled high with on-board resistor
  delay(1); //Allow Si4703 to come out of reset
  //
  Serial.print("VOID LOOOP");
 max14521_init;
}
void loop(){
  max14521_init();
 //ENABLE 0x01
  Address=POWERMODE;
  DATA=0x81;
  max14521_Write();
  
  //EL_FREQ 0x02
  Address=EL_FREQ;
  DATA=1;
  max14521_Write();
   //EL_SHAPE 0x03
  Address=EL_SHAPE;
  DATA=0x40;
  max14521_Write();
  //BOOST 04
  Address=BOOST_CONVERTER;
  DATA=0xdF;
  max14521_Write();
   //EL_AUDIO
  Address=AUDIO;
  DATA=40;
  max14521_Write();
  //
  Serial.print("Scrittura terminata");
  delay(3000);
}
void max14521_init(void) {
  Serial.println("Initializing I2C and Max14521");
  pinMode(resetPin, OUTPUT);
  delay(1);
  pinMode(SDIO, OUTPUT); //SDIO is connected to A4 for I2C
  digitalWrite(SDIO, LOW); //A low SDIO indicates a 2-wire interface
  delay(1);
  Wire.begin(); //Now that the unit is reset and I2C inteface mode, we need to begin I2C
}
byte max14521_Write (void) {
    Wire.beginTransmission(0x78);
    byte ack = Wire.endTransmission();
    if(ack != 0) { //We have a problem! 
    Serial.print("Write FailIDCHIP:"); //No ACK!
    Serial.println(ack, DEC); //I2C error: 0 = success, 1 = data too long, 2 = rx NACK on address, 3 = rx NACK on data, 4 = other error
    return(FAIL);
    }
    return(SUCCESS);
    //ADDRESS REGISTER
    Wire.write(Address);
    byte ack1 = Wire.endTransmission();
    if(ack1 != 0) { //We have a problem! 
    Serial.print("Write Fail:address"); //No ACK!
    Serial.println(ack, DEC); //I2C error: 0 = success, 1 = data too long, 2 = rx NACK on address, 3 = rx NACK on data, 4 = other error
    return(FAIL);
    }
    return(SUCCESS);
    //DATA
    Wire.write(DATA);
    byte ack2 = Wire.endTransmission();
    if(ack2 != 0) { //We have a problem! 
    Serial.print("Write FailDATA:"); //No ACK!
    Serial.println(ack, DEC); //I2C error: 0 = success, 1 = data too long, 2 = rx NACK on address, 3 = rx NACK on data, 4 = other error
    return(FAIL);
    }
    return(SUCCESS);
    
}

Wire.beginTransmission(0x78);
Wire.write(0x02); // sceglie il registro

Wire.write(0x81); // invia 0x81 (hex) 10000001 (binary) bit 7-0

Wire.endTransmission();

OK grazie, nel datasheet viene indicato uno zero subito dopo l’indirizzo del chip, prima dell’acknowledge, lo zero identifica il read/write per l’indirizzo credo. Per adesso non mi dà errori nella scrittura sebbene non funzioni ancora un tubo di nulla. Come si può fare a fornire quello zero?
Inoltre il datasheet richiede la start condition ( da me indicata con la void initi_max14521) ad ogni inizio di scrittura, io la fornisco solo all’inizio ciclo e non ricevo errori…
Riuscite a capire qualcosa?

Grazie infinite

Avete qualche idea?

Il datasheet indica di scrivere in 4 registri il valore 0Ah per aggiornare la tensione di uscita, 0Ah che valore ha in esadecimale? come posso fare a scriverlo?
Inoltre è possibile e come leggere i registri appena settati per controllare di aver scritto i valori giusti?
Grazie

0Ah è già in esadecimale (0x0A) per scriverlo devi fare come dice brunello (ovviamente settando l'indirizzo del registro e il il tuo valore):

Brunello:
Wire.beginTransmission(0x78);
Wire.write(0x02); // sceglie il registro

Wire.write(0x81); // invia 0x81 (hex) 10000001 (binary) bit 7-0

Wire.endTransmission();

OK ho corretto ancora il codice grazie dei suggerimenti, purtroppo però non funziona ancora provo a ripostare il codice se avete tempo e pazienza di guardarlo vi ringrazio molto. Purtroppo non riesco a capire perchè ma effettuando la lettura di qualsiasi registro il valore è sempre 255. La lettura è inserita nel codice a seguire prima della fine del void loop.
Cosa sbaglio? quello zero richiesto nel datasheet a pagina 17 per indicare il write l’ho inserito correttamente?
Grazie

#include <Wire.h>
int resetPin = 2;

uint8_t max14521_registers[8];
#define FAIL  0
#define SUCCESS  1
#define DEVICE_ID 0x00
#define POWERMODE  0x01
#define EL_FREQ  0x02
#define EL_SHAPE  0x03
#define BOOST_CONVERTER 0x04
#define AUDIO  0x05
#define EL1OUT  0x06
#define EL2OUT  0x07
#define EL3OUT  0x08
#define EL4OUT  0x09
#define MAX14521 0x00 
int SDIO = A4; //SDA/A4 on Arduino
int SCLK = A5; //SCL/A5 on Arduino
int Address;
byte DATA;
byte printBuffer;
boolean zero=0;
void setup() {   
  pinMode(2,OUTPUT);  
  pinMode(13, OUTPUT);
  pinMode(A2,OUTPUT);
  pinMode(A4,OUTPUT);
  pinMode(A5,OUTPUT);
  Serial.begin(57600);
  Serial.println();
  //CLEAR REGISTER
  digitalWrite(resetPin, LOW); //Put Si4703 into reset
  delay(1); //Some delays while we allow pins to settle
  digitalWrite(resetPin, HIGH); //Bring Si4703 out of reset with SDIO set to low and SEN pulled high with on-board resistor
  delay(1); //Allow Si4703 to come out of reset
  //
}
void loop(){
  max14521_init();
 //ENABLE 0x01
  Address=POWERMODE;
  DATA=1;
  max14521_Write();
  max14521_init();
  //EL_FREQ 0x02
  Address=EL_FREQ;
  DATA=191;
  max14521_Write();
  
  max14521_init();
   //EL_SHAPE 0x03
  Address=EL_SHAPE;
  DATA=68;
  max14521_Write();
  
  max14521_init();
  //BOOST 04
  Address=BOOST_CONVERTER;
  DATA=137;
  max14521_Write();
  
  max14521_init();
   //EL_AUDIO
  Address=AUDIO;
  DATA=64;
  max14521_Write();
  //
  //SET EVERY VOLTAGE
  max14521_init();
  Address=EL1OUT;
  DATA=223;
  max14521_Write();
  max14521_init();
  Address=EL2OUT;
  DATA=223;
  max14521_Write();
   max14521_init();
  Address=EL3OUT;
  DATA=223;
  max14521_Write();
  max14521_init();
  Address=EL4OUT;
  DATA=223;
  max14521_Write();
    //UPDATE OALL
  max14521_init();
  Address=EL1OUT;
  DATA=0x0A;
  max14521_Write();
  max14521_init();
  Address=EL2OUT;
  DATA=0x0A;
  max14521_Write();
   max14521_init();
  Address=EL3OUT;
  DATA=0x0A;
  max14521_Write();
  max14521_init();
  Address=EL4OUT;
  DATA=0x0A;
  max14521_Write();

  Wire.beginTransmission(0x78);
  Wire.requestFrom(7, 1);
  byte x=Wire.read();
  Serial.println(x);

  Serial.println("Scrittura terminata");
  delay(3000);
}
void max14521_init(void) {
  Serial.println("Initializing I2C and Max14521");

  pinMode(SCLK, OUTPUT); //SDIO is connected to A4 for I2C
  pinMode(SDIO, OUTPUT); //SDIO is connected to A4 for I2C
   digitalWrite(SDIO, HIGH); //A low SDIO indicates a 2-wire interface
   digitalWrite(SCLK, HIGH); //A low SDIO indicates a 2-wire interface
   delay(1);
  digitalWrite(SDIO, LOW); //A low SDIO indicates a 2-wire interface
   digitalWrite(SCLK, LOW); //A low SDIO indicates a 2-wire interface
  delay(1);
  Wire.begin(); //Now that the unit is reset and I2C inteface mode, we need to begin I2C
}
byte max14521_Write (void) {
    Wire.beginTransmission(0x78);
    Wire.write(zero); // lo zero indica scrittura  1 lettura Rif. pag 17 datasheet
    byte ack = Wire.endTransmission();
    if(ack != 0) { //We have a problem! 
    Serial.print("Write FailIDCHIP:"); //No ACK!
    Serial.println(ack, DEC); //I2C error: 0 = success, 1 = data too long, 2 = rx NACK on address, 3 = rx NACK on data, 4 = other error
    return(FAIL);
    }
    return(SUCCESS);
    //ADDRESS REGISTER
    Wire.write( max14521_registers[Address]);
    byte ack1 = Wire.endTransmission();
    if(ack1 != 0) { //We have a problem! 
    Serial.print("Write Fail:address"); //No ACK!
    Serial.println(ack1, DEC); //I2C error: 0 = success, 1 = data too long, 2 = rx NACK on address, 3 = rx NACK on data, 4 = other error
    return(FAIL);
    }
    return(SUCCESS);
    //DATA
    Wire.write(DATA);
    byte ack2 = Wire.endTransmission();
    if(ack2 != 0) { //We have a problem! 
    Serial.print("Write FailDATA:"); //No ACK!
    Serial.println(ack2, DEC); //I2C error: 0 = success, 1 = data too long, 2 = rx NACK on address, 3 = rx NACK on data, 4 = other error
    return(FAIL);
    }
    return(SUCCESS);
    pinMode(SCLK, OUTPUT); //SDIO is connected to A4 for I2C
    pinMode(SDIO, OUTPUT); //SDIO is connected to A4 for I2C
    digitalWrite(SCLK, HIGH); //A low SDIO indicates a 2-wire interface
    delay(1);
    digitalWrite(SDIO, HIGH); //A low SDIO indicates a 2-wire interface
   
}

togli tutta questa roba:

pinMode(SCLK, OUTPUT); //SDIO is connected to A4 for I2C
  pinMode(SDIO, OUTPUT); //SDIO is connected to A4 for I2C
   digitalWrite(SDIO, HIGH); //A low SDIO indicates a 2-wire interface
   digitalWrite(SCLK, HIGH); //A low SDIO indicates a 2-wire interface
   delay(1);
  digitalWrite(SDIO, LOW); //A low SDIO indicates a 2-wire interface
   digitalWrite(SCLK, LOW); //A low SDIO indicates a 2-wire interface

la lettura non si fa così:

    Wire.beginTransmission(0x78);
    Wire.write(zero); // lo zero indica scrittura  1 lettura Rif. pag 17 datasheet
    byte ack = Wire.endTransmission();

ma usi l'apposita funzione requestFrom(), perchè l'indirizzo i2c deve flippare un bit per indicare che è in lettura.

ok ora provo però in teoria quella sequenza l'ho letta dal datasheet per inizializzare la comunicazione dicevano fosse necessario, in effeti non cambia nulla e per la lettura non ho usato quelle istruzioni che invece intendevo usare per indicare lo zero (zero booleana indicata in testa al programma) che nel protocollo dice facia capire al chip che sto scrivendo e non leggendo.
Le operazioni di lettura le ho effettuate così in mezzo al programma:

  Wire.beginTransmission(0x78);
  Wire.requestFrom(7, 1);
  byte x=Wire.read();
  Serial.println(x);

ho provato a togliere le istruzioni :

\pinMode(SCLK, OUTPUT); //SDIO is connected to A4 for I2C
  pinMode(SDIO, OUTPUT); //SDIO is connected to A4 for I2C
   digitalWrite(SDIO, HIGH); //A low SDIO indicates a 2-wire interface
   digitalWrite(SCLK, HIGH); //A low SDIO indicates a 2-wire interface
   delay(1);
  digitalWrite(SDIO, LOW); //A low SDIO indicates a 2-wire interface
   digitalWrite(SCLK, LOW); //A low SDIO indicates a 2-wire interface\[code]
e confermo che non cambia nulla continua  a trasmettere ma la lettura fornisce sempre 255 in Output... 
sto sclerando...