[Risolto] Invio dati i2c su PCF8574

Che ne dite di controllare 2 PCF8575 con 16 linee pseudo I/O - I2C con Arduino ma utilizzando un nuovo compilatore potentissimo con una sintassi simile al basic? vi mostro l'esempio:

'*******************************************************************************
'*      [ Gestione tramite I2C di due PCF8575  I/O expander con Arduino ]      *
'*  il primo PCF all'indirizzo x43 legge dei pulsanti connessi sulle linee Inp *
'*  L'uscita INT del PCF è connessa                                            *
'*  all'ingresso INT2 dell' ATmega2560.                                        *
'*  il Micro legge i dati provenienti dal primo PCF e li trasmette al secondo  *
'*                                                                             *
'*******************************************************************************

$regfile = "M2560def.dat"
$crystal = 16000000
$hwstack = 128
$swstack = 128
$framesize = 128
$baud = 57600

Config Scl = Portd.0
Config Sda = Portd.1
Config Int2 = Falling

Enable Interrupts
Enable Int2
On Int2 Int_2

Dim Value(2) As Byte
Dim S As String * 20

'------------------[ configura il PCF8575 2 in uscita ]-------------------------
 I2cstart
   I2cwbyte &H40
   I2cwbyte &HFF
   I2cwbyte &HFF
 I2cstop

'-------------------------------------------------------------------------------
Do
  nop
Loop

End
'------------------[ gestione interrupt generato dal PCF8575 1 ]----------------
Int_2:
   I2cstart                                                 'generate start per lettura PCF8575  1
   I2cwbyte &H43                                            'slave address
   I2crbyte Value(1) , Ack                                  'leggi primo byte
   I2crbyte Value(2) , Ack                                  'leggi secondo byte
   I2cstop

   Print Hex(value(1)) ; " " ; Hex(value(2))                'stampa sul terminale

   I2cstart                                                 'genera start per scrittura PCF7575 2
   I2cwbyte &H40                                            'slave address
   I2cwbyte Value(1)                                        'scrivi primo byte
   I2cwbyte Value(2)                                        'scrivi secondo byte
   I2cstop

Return
'-------------------------------------------------------------------------------

tubincolo: Che ne dite di controllare 2 PCF8575 con 16 linee pseudo I/O - I2C con Arduino ma utilizzando un nuovo compilatore potentissimo con una sintassi simile al basic? vi mostro l'esempio:

'*******************************************************************************
'*      [ Gestione tramite I2C di due PCF8575  I/O expander con Arduino ]      *
'*  il primo PCF all'indirizzo x43 legge dei pulsanti connessi sulle linee Inp *
'*  L'uscita INT del PCF è connessa                                            *
'*  all'ingresso INT2 dell' ATmega2560.                                        *
'*  il Micro legge i dati provenienti dal primo PCF e li trasmette al secondo  *
'*                                                                             *
'*******************************************************************************

$regfile = "M2560def.dat" $crystal = 16000000 $hwstack = 128 $swstack = 128 $framesize = 128 $baud = 57600

Config Scl = Portd.0 Config Sda = Portd.1 Config Int2 = Falling

Enable Interrupts Enable Int2 On Int2 Int_2

Dim Value(2) As Byte Dim S As String * 20

'------------------[ configura il PCF8575 2 in uscita ]------------------------- I2cstart    I2cwbyte &H40    I2cwbyte &HFF    I2cwbyte &HFF I2cstop

'------------------------------------------------------------------------------- Do   nop Loop

End '------------------[ gestione interrupt generato dal PCF8575 1 ]---------------- Int_2:    I2cstart                                                 'generate start per lettura PCF8575  1    I2cwbyte &H43                                            'slave address    I2crbyte Value(1) , Ack                                  'leggi primo byte    I2crbyte Value(2) , Ack                                  'leggi secondo byte    I2cstop

   Print Hex(value(1)) ; " " ; Hex(value(2))                'stampa sul terminale

   I2cstart                                                 'genera start per scrittura PCF7575 2    I2cwbyte &H40                                            'slave address    I2cwbyte Value(1)                                        'scrivi primo byte    I2cwbyte Value(2)                                        'scrivi secondo byte    I2cstop

Return '-------------------------------------------------------------------------------

si ne ho tre a casa..ma come lo mando il programma ad arduino??

Per compilare il codice sopra riportato hai bisogno di un sistema di sviluppo chiamato Bascom-AVR e compilare il sorgente per il micro ATmega2560 o altri AVR, in base al modello di Arduino. Volendo potresti usare invece del protocollo I2C software l'interfaccia HW TWI per velocizzare fino a 400Khz la frequenza di clock su SCL del micro.

Cmq, Se vuoi saperne di più ti puoi registrare liberamente nel forum ufficiale italiano:

http://www.delucagiovanni.com/public/phpbb3/index.php

per quella interfaccia intendi una cosa del genere:?

unsigned char I2C_Start_Condition()
{
    unsigned char twi_check;
   
    TWCR = 0xE4;                //Clear flag,send start condition and enable TWI..
    while (!(TWCR & 0x80))      //Wait for transmission complete..
        ; 
   
    twi_check = (TWSR & 0xF8);  //Check transmission..
    if ((twi_check != 0x08) && (twi_check !=0x10))
        return 0;               //Return failure..
   
    else
        return 1;               //Else return success                                 
}

void I2C_Stop_Condition()
{
    TWCR = 0x94;                //Clear flag,send stop condition and enable TWI..
    while (!(TWCR & 0x10))      //Wait for transmission complete..
        ;
}

unsigned char I2C_Send_Byte(unsigned char data)
{
    unsigned char twi_check;
   
    TWDR = data;                //Put data on TWDR..
    TWCR = 0xC4;                //Clear flag and enable TWI..
    while (!(TWCR & 0x80))      //Wait for transmission complete..
        ;
       
    twi_check = (TWSR & 0xF8);  //Check transmission..
    if ((twi_check != 0x08) && (twi_check !=0x10))
        return 0;               //Return failure..
   
    else
        return 1;               //Else return success     
}

unsigned char I2C_Receive_Byte()
{
    TWCR = 0xC4;                //Clear flag and enable TWI..
    while (!(TWCR & 0x80))      //Wait for transmission complete..
        ;
       
    return TWDR;
}
void STA013_Write_Reg(unsigned char address,unsigned char data)
{
    I2C_Start_Condition();                  //Send start condition..
    I2C_Send_Byte(WRITE_VALUE);             //Send value for writing..
    I2C_Send_Byte(address);                 //Send address for writing..
    I2C_Send_Byte(data);                    //Send data..
    I2C_Stop_Condition();                   //Send stop condition..
}

//Function for reading a register from STA013..
unsigned char STA013_Read_Reg(unsigned char address)
{
    unsigned char data;
   
    I2C_Start_Condition();                  //Send start condition..
    I2C_Send_Byte(WRITE_VALUE);             //Send value for writing..
    I2C_Send_Byte(address);                 //Send address for writing..
    I2C_Stop_Condition();                   //Send stop condition..
    I2C_Start_Condition();                  //Send start condition..
    I2C_Send_Byte(READ_VALUE);              //Send value for writing..
    data = I2C_Receive_Byte();              //Read data returned..
    I2C_Stop_Condition();                   //Send stop condition..
   
    return data;                            //Return the value of register..
}

comunque appena ho tempo mi iscrivo; per il compilatore ho capito ;) Grazie mille, Igor PS: farò delle prove naturalmente e ti faccio sapere sperando non me ne dimentichi :grin:

Hey Igor, non mi hai risposto al messaggio precedente !

Prova anche a mettere un delay(2000) dopo l'invio dei dati IIC.

acik: Hey Igor, non mi hai risposto al messaggio precedente !

Prova anche a mettere un delay(2000) dopo l'invio dei dati IIC.

mmm, no seriamente ti avevo rispsoto :astonished: il caldo fa brutti scherzi.. cmq io i dati li invio tramite seriale..ci scrivo su un numero..forse il prblema sta poprio in quello che scrivo ma non penso...anche se scrivevo un altro numero mi usciva un carattere sempre diverso e onvece no..escono sempre gli stessi dati.. PS: proverò anche come mi hai detto..ma stesera

igor97: mmm, no seriamente ti avevo rispsoto :astonished: il caldo fa brutti scherzi..

Mi hai risposto alla domanda "Innanzitutto dovresti dire cosa invii alla seriale. Come lo invii ?"

Usi Hyperterminal ?

meno male che domani mi vado a riposare il cervello in villa.. Uso l'ide di arduino...

tubincolo: Per compilare il codice sopra riportato hai bisogno di un sistema di sviluppo chiamato Bascom-AVR e compilare il sorgente per il micro ATmega2560 o altri AVR, in base al modello di Arduino. Volendo potresti usare invece del protocollo I2C software l'interfaccia HW TWI per velocizzare fino a 400Khz la frequenza di clock su SCL del micro.

Cmq, Se vuoi saperne di più ti puoi registrare liberamente nel forum ufficiale italiano:

http://www.delucagiovanni.com/public/phpbb3/index.php

Ma è un caso che il tuo avatar sia uguale al logo del sito che hai linkato oppure no? E perché non ne possiamo parlare qui, del BASCOM, ma bisogna registrarsi su un altro forum? Sono informazioni riservate o è un tentativo di portare nuovi iscritti in quel forum? ;)

@leo: io ho capito che lui voleva solo consigliarmi un forum su cui apprfondire il bascom...

PERO' del bascom sarebbe anche bello parlre qui come megatopic ;)

igor97: @leo: io ho capito che lui voleva solo consigliarmi un forum su cui apprfondire il bascom...

PERO' del bascom sarebbe anche bello parlre qui come megatopic ;)

Difatti è quello che volevo far intendere io senza però dirlo. Perché consigliare di migrare su un altro forum quando si può approfondire la cosa qui, per il beneficio dei più? Magari è un argomento che potrebbe interessare.

;)

Scusatemi tanto se ho suscitato qualche malinteso,

ma in tutti i forum si può parlare, condividere esperienze, scambiare opinioni diverse..... nel rispetto reciproco. non vedo quindi nessun problema se qualcuno vi suggerisce l'iscrizione ad un nuovo forum di certo non vi sta invitando o costringendo a cancellarvi da questo. :)

Il forum che avevo consigliato è il forum ufficiale italiano segnalato da MCSELEC.COM l'azienda produttrice del sistema di sviluppo BASCOM-AVR 100% compatibile con la piattaforma Arduino. Il banner di segnalazione del forum è presente sulla prima pagina del sito come vedesi in questo topic http://www.delucagiovanni.com/public/phpbb3/viewtopic.php?f=14&t=309

Ecco perchè intendevo far conoscere quel forum... perchè li, noi siamo in diretto contatto con gli sviluppatori del sistema IDE e del compilatore e possiamo chiedere di effettuare anche fix, modifiche ed aggiunte di custom instruction che potranno giovarci di volta in volta nelle nostre applicazioni. (vi sembra poco?).

Inoltre se a qualcuno può interessare il forum italiano comprende anche sezioni dedicate alla Robotica, alle FPGA, al linguaggio di descrizione hardware VHDL e alla intelligenza e visione artificiale.

Scusate ancora, Ciao a tutti e alla prossima. :)

Nessuno se l'è presa, solo che alle volte basterebbe dire le cose come stanno, nessuno ti mette in croce. ;) Potevi benissimo dire: gente, quel forum è mio/lo gestisco io/lo frequento e può aiutarvi ad apprendre il BASCOM. Tutto qui XD XD

igor97: meno male che domani mi vado a riposare il cervello in villa.. Uso l'ide di arduino...

Allora prova a inviare la "A" (maiuscolo), che sarebbe il codice 65. (64+1) Poi prova a inviare "B", che sarebbe il codice 66. (64+2) Poi prova a inviare "D", che sarebbe il codice 68. (64+4)

Vediamo che ne esce fuori :-)

acik:

igor97:
meno male che domani mi vado a riposare il cervello in villa…
Uso l’ide di arduino…

Allora prova a inviare la “A” (maiuscolo), che sarebbe il codice 65. (64+1)
Poi prova a inviare “B”, che sarebbe il codice 66. (64+2)
Poi prova a inviare “D”, che sarebbe il codice 68. (64+4)

Vediamo che ne esce fuori :slight_smile:

scusala tarda risposta ma ho avuto da fare coi progetti… :S

ho fatto questa prova e non va lo stesso… lo sketch che ho usato è :

#include <Wire.h>
void setup()
{
Serial.begin(115200);
Wire.begin();
}
void loop()
{
if (Serial.available()>0)
{
int data = Serial.read();
Wire.beginTransmission(56);
Wire.send(data);
Wire.endTransmission();
}
}

Ma che versione dell'IDE di arduino stai usando? A partire dalla 1.0, il metodo .send della lib Wire è stato sostituito dal metodo .write. Nello specifico, il reference dice che se scrivi Wire.write(valore) la lib spedisce un byte. Ma tu hai dichiarato data di tipo int. Forse è per questo che non va

leo72: Ma che versione dell'IDE di arduino stai usando? A partire dalla 1.0, il metodo .send della lib Wire è stato sostituito dal metodo .write. Nello specifico, il reference dice che se scrivi Wire.write(valore) la lib spedisce un byte. Ma tu hai dichiarato data di tipo int. Forse è per questo che non va

il comando wire.send l'avevo gia sostituito con write (si uso 1.0).. quindi il parametro accettato da wire.write è solo byte?? come faccio ad inviarli un numero decimale? e poi perchè non posso scrivere tra parentesi direttamente il byte'? Grazie mille

Puoi scrivere il byte tra parentesi. Certo che puoi. Send.write(65) spedisce il byte 65. Ma tu hai scritto: int data; Wire.send(data)

Così il compilatore esegue il casting di data da int a byte, che ne risulterà? Spedirai il byte meno significativo o quello più significativo?

Quindi se hai un numero di tipo int, devi spedirlo in 2 byte distinti, con lowByte e highByte. Un numero decimale, float, occupa 4 byte, e richiede qualche passaggio in più.

leo72: Puoi scrivere il byte tra parentesi. Certo che puoi. Send.write(65) spedisce il byte 65. Ma tu hai scritto: int data; Wire.send(data)

Così il compilatore esegue il casting di data da int a byte, che ne risulterà? Spedirai il byte meno significativo o quello più significativo?

Quindi se hai un numero di tipo int, devi spedirlo in 2 byte distinti, con lowByte e highByte. Un numero decimale, float, occupa 4 byte, e richiede qualche passaggio in più.

Appena torno a casa riprovo però mi ricordo che non compilava se scrivevo il byte direttamente nelle parentesi Scrivevo wire.write(0becc)