Problema I2C Attiny85-Arduino

Ebbene, eccomi qua di nuovo, purtroppo un altro problema nel mio interminabile progetto si è presentato e chiedo delucidazioni ai master! :slight_smile:
Quindi la questione è che non riesco a far comunicare correttamente Arduino ed un ATtiny85 attraverso I2C.
La questione lato hardware non mi pare molto difficile SDA e SCL con pull-ups e finisce così, o vado errato?
Il problema consiste nel fatto che da quanto ho capito la libreria TinyWireS è rimasta con i vecchi metodi della Wire giusto? E proprio non riesco ad integrare i due codici…
Allego i 2 file che ho utilizzato (scusatemi se ho fatto errori banali ma ultimamente non ho tempo e faccio le cose di fretta appena posso)

Sono sicuro di un vostro aiuto, :wink:
MA

masteri2c.ino (655 Bytes)

slavei2c.ino (346 Bytes)

Quando si chiede aiuto bisognerebbe dare tutte le info possibili, ad esempio l’IDE usato e l’esatto errore che si riceve, altrimenti si va a tentativi … :roll_eyes:

MasterArchi:
La questione lato hardware non mi pare molto difficile SDA e SCL con pull-ups e finisce così, o vado errato?

Il core di Arduino attiva le pull-up interne sui pin A4 e A5, quindi se la distanza tra i 2 chip è molto breve puoi evitare di aggiungere quelle esterne. Al max aggiungi 2 R d 2K2.

Il problema consiste nel fatto che da quanto ho capito la libreria TinyWireS è rimasta con i vecchi metodi della Wire giusto?

Che intendi per “vecchi metodi” (vedi? senza gli errori che ottieni non si capisce).
Ricordati che la TinyWireM (se non è stata modificata ultimamente) presupponeva l’uso con chip tarati a 1 MHz e con clock maggiori dovevi modificare il codice.

leo72:
Quando si chiede aiuto bisognerebbe dare tutte le info possibili, ad esempio l'IDE usato e l'esatto errore che si riceve, altrimenti si va a tentativi ... :roll_eyes:

Il core di Arduino attiva le pull-up interne sui pin A4 e A5, quindi se la distanza tra i 2 chip è molto breve puoi evitare di aggiungere quelle esterne. Al max aggiungi 2 R d 2K2.

Allora la IDE che utilizzo è la 1.0.5-r2 ed ho aggiunto alle librerie la TinyWireS che ho scaricato dal repo di rambo : TinyWire/TinyWireS at master · rambo/TinyWire · GitHub

Come resistenze di pull-up invece sto usando due da 1K, vanno bene lo stesso (si l'attiny è vicinissimo)?

leo72:
Che intendi per "vecchi metodi" (vedi? senza gli errori che ottieni non si capisce).
Ricordati che la TinyWireM (se non è stata modificata ultimamente) presupponeva l'uso con chip tarati a 1 MHz e con clock maggiori dovevi modificare il codice.

Come ho già detto sto utilizzando la TinyWireS che da quanto ho letto supporta pienamente gli 8MHz, per quanto riguarda gli errori che ottengo : quando apro il monitor seriale di arduino per vedere se riceve correttamente non mostra alcun segno di vita. Quindi suppongo che l'errore sia parte software, ma proprio non riesco a capire dove sia. Per vecchi metodi della Wire intendevo che prima in essa si utilizzava send() se non sbaglio mentre ora si usa write(). Giusto?

Scusate la mancanza di precisazioni nel primo post, spero di aver scritto tutto. :slight_smile:

Grazie della risposta,
MA

Up

 for (i; i<Wire.available(); i++){
      input[i] = Wire.read();
    }
    y = atoi(input);

atoi ha bisogno di un Zero come fine della stringa.

 for (i; i<Wire.available(); i++){
      input[i] = Wire.read();
    }
    input[i+1]=0;
    y = atoi(input);

Inoltre dovresti definire la grandezza del array input; senó sovrascrivi altre variabili.

Ciao Uwe

Grazie della risposta Uwe!

Tuttavia ho semplificato al massimo il codice (e mi sono reso conto di alcuni errori imbarazzanti :cold_sweat: ), ma anche in questa situazione sembra che l’attiny non trasmetta nulla e dalla seriale di arduino leggo così : "Dato ricevuto : " :~

A questo punto ho paura di aver fatto i collegamenti sbagliati : ho collegato all’Attiny l’alimentazione dello stesso arduino, il pin A5 al pin 2 dell’attiny e il pin A4 al pin 0 con resistenze da pull-up da 1K. Ho sbagliato qualcosa?

Ecco il codice dell’Attiny Slave :

#include <TinyWireS.h>
#define ADDRESS  0x13  // Indirizzo I2C

const byte led1 = 1;  
int value = 30;

void setup() {
  TinyWireS.begin(ADDRESS); // Inizializzo la comunizazione I2C
  pinMode(led1, OUTPUT);
}

void loop() {
  TinyWireS.onRequest(Send); // Alla richiesta richiama Send()
}

void Send() {
  TinyWireS.send(value);   // Invia un valore di prova
  digitalWrite(led1, HIGH);
  delay(100);
  digitalWrite(led1, LOW);
  delay(300);
}

Ecco quello del Master lato Arduino :

#include <Wire.h>
#define ADDRESS 0x13

int i = 0;
char input[3];

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop()
{
  Wire.requestFrom(ADDRESS, 6);    // request 6 bytes from slave device 0x13
  if(Wire.available()>0)
  { 
    for (i; i<Wire.available(); i++){
      input[i] = Wire.read();
    }
    Serial.print("Dato ricevuto : ");
    Serial.println(input);
    i=0;
    delay(500);
  }  
}

Ok, credo di aver capito il problema anche se ho ancora qualche dubbio, a quanto pare send() supporta l'invio di un solo byte e int ne contiene 4. Ma considerando quindi un'ipotetica struttura void send (byte in) questa stessa funzione non dovrebbe portare ad un cast implicito automatico?

Grazie a tutti, :slight_smile:
MA

Su Arduino il tipo "int" è uno "short int", quindi 16 bit, 2 byte.
Il casting automatico è in realtà un troncamento, nel senso che se gli passi un int e lui vuole un byte, il dato viene troncato coi risultati che puoi immaginarti.

Io ho lavorato con l'I2C sui Tiny, ho anche scritto un paio di guide sia per IDE 1.5 che per IDE 1.0
http://www.leonardomiliani.com/2013/guida-allutilizzo-dei-micro-attiny-con-lide-arduino-1-5-x/
http://www.leonardomiliani.com/2012/guida-agli-attiny-aggiornata/

La seconda è stata scritta per l'IDE 0022 ma le modifiche alle lib valgono lo stesso, guarda un pò se ti possono aiutare.

Grazie delle guide leo! :slight_smile: Ho dato una lettura alle tue guide, tuttavia non sono ancora riuscito ad inviare più di un byte da attiny, quindi penso che il problema sia lato software. Ripropongo ancora una volta una domanda : Le pull-up da 1K vanno bene lo stesso?
Ed ora che provo a trasmettere un char perchè non funziona, il char non è 1 byte?? Per piacere, il progetto è urgente… :~
Quello che ottengo in seriale è roba incomprensibile, certe volte anche nulla. :drooling_face:

MASTER :

#include <Wire.h>
#define ADDRESS 0x13

int i = 0;
char input[6];

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop()
{
  Wire.requestFrom(ADDRESS, 6);    // request 2 bytes from slave device 0x13
  if(Wire.available()>0)
  { 
    for (i=0; i<Wire.available(); i++){
      input[i] = (char) Wire.read();
    }
    Serial.print("Dato ricevuto : ");
    Serial.println(input);
  }  
}

SLAVE:

 #include <TinyWireS.h>
#include <string.h>
#define ADDRESS  0x13  // Indirizzo I2C

const byte led1 = 1;  
const byte led2 = 3;
char stringa[] = {
  "Te2910"};

void setup() {
  TinyWireS.begin(ADDRESS); // Inizializzo la comunizazione I2C
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);

  digitalWrite(led1, HIGH);  // Show it's alive
  digitalWrite(led2, HIGH);
  tws_delay(500);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  tws_delay(1000);
}

void loop() {
  TinyWireS.onRequest(Send); // Alla richiesta richiama Send
}

void Send() {
  for (int i=0; i<strlen(stringa); i++){
    TinyWireS.send((byte) stringa[i]);
    digitalWrite(led1, HIGH);
    tws_delay(50);
    digitalWrite(led1, LOW);
    tws_delay(50);
  }
  digitalWrite(led2, HIGH); // Successfully transmitted
  tws_delay(100);
  digitalWrite(led2, LOW);
  tws_delay(1000);
}

Pull-up da 1K sono troppo alte. Considera anche la corrente fornita dalle pull-up interne al chip. Come ti ho detto delle R da 1K8/2K2 sono più che sufficienti.

Non ho poi dato un'occhiata al tuo progetto, ma partiamo da ciò che funziona... hai provato il programmino di test che ho messo nelle mie guide? Quelli funzionano per certo (provati e testati).