Portál AbcLinuxu, 8. května 2025 07:16

Dotaz: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c

25.12.2021 20:32 zdenek2008 | skóre: 26
Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
Přečteno: 398×
Odpovědět | Admin
Chtel bych si vypisovat co se deje v ATtiny85 tak, ze poslu informace do Pi Pica pres i2c a Pico prijate informace vypise na pc v konzoli Thonny. Dostal jsem se ke stadiu ze t85 poslusne blika sverenou diodou takze program je alespon syntakticky funkcni. Pico sice neprotestuje, ale nic nevypisuje. Propojeni by snad melo byt spravne, hodiny jsou v obou cipech v puvodnim nastaveni, alespon jsem nic vedome nemenil. Zde je kod pro t85 jako master:
#include (nepovolena sipka)TinyWireM.h(nepovolena sipka)                  // I2C Master lib for ATTinys which use USI

#define PICO_ADDR   0x41 //0x055 zakladni adresa pica

int led = 3;


void setup(){
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
  
  TinyWireM.begin();                    // initialize I2C lib
  delay(2000);
}


void loop(){
  digitalWrite(led, HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(1000);
  digitalWrite(led, HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(1000);
  digitalWrite(led, HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(2000);
  Posli_jeden_byte();  
  Posli_text();
}


void Posli_jeden_byte(){
  TinyWireM.beginTransmission(PICO_ADDR);
  TinyWireM.send(0xAB);
  TinyWireM.endTransmission();
}


void Posli_text(){
  TinyWireM.beginTransmission(PICO_ADDR);
  char myString[12] = "Nazdar!";
  for(byte i = 0; i <= strlen(myString); i++)
  {
      TinyWireM.send(myString[i]);
  }
  TinyWireM.endTransmission();
}
A zde kod pro Pico jako slave:
from machine import mem32, Pin

class i2c_slave:
    I2C0_BASE = 0x40044000
    I2C1_BASE = 0x40048000
    IO_BANK0_BASE = 0x40014000
    
    mem_rw =  0x0000
    mem_xor = 0x1000
    mem_set = 0x2000
    mem_clr = 0x3000
    
    IC_CON = 0
    IC_TAR = 4
    IC_SAR = 8
    IC_DATA_CMD = 0x10 
    IC_RX_TL = 0x38
    IC_TX_TL = 0x3C
    IC_CLR_INTR = 0x40
    IC_ENABLE = 0x6c
    IC_STATUS = 0x70
    
    def write_reg(self, reg, data, method=0):
        mem32[ self.i2c_base | method | reg] = data
        
    def set_reg(self, reg, data):
        self.write_reg(reg, data, method=self.mem_set)
        
    def clr_reg(self, reg, data):
        self.write_reg(reg, data, method=self.mem_clr)
                
    def __init__(self, i2cID = 0, sda=0,  scl=1, slaveAddress=0x41):
        self.scl = scl
        self.sda = sda
        self.slaveAddress = slaveAddress
        self.i2c_ID = i2cID
        if self.i2c_ID == 0:
            self.i2c_base = self.I2C0_BASE
        else:
            self.i2c_base = self.I2C1_BASE
        
        # 1 Disable DW_apb_i2c
        self.clr_reg(self.IC_ENABLE, 1)
        # 2 set slave address
        # clr bit 0 to 9
        # set slave address
        self.clr_reg(self.IC_SAR, 0x1ff)
        self.set_reg(self.IC_SAR, self.slaveAddress &0x1ff)
        # 3 write IC_CON  7 bit, enable in slave-only
        self.clr_reg(self.IC_CON, 0b01001001)
        # set SDA PIN
        mem32[ self.IO_BANK0_BASE | self.mem_clr |  ( 4 + 8 * self.sda) ] = 0x1f
        mem32[ self.IO_BANK0_BASE | self.mem_set |  ( 4 + 8 * self.sda) ] = 3
        # set SLA PIN
        mem32[ self.IO_BANK0_BASE | self.mem_clr |  ( 4 + 8 * self.scl) ] = 0x1f
        mem32[ self.IO_BANK0_BASE | self.mem_set |  ( 4 + 8 * self.scl) ] = 3
        # 4 enable i2c 
        self.set_reg(self.IC_ENABLE, 1)


    def any(self):
        # get IC_STATUS
        status = mem32[ self.i2c_base | self.IC_STATUS]
        # check RFNE receive fifio not empty
        if (status &  8) :
            return True
        return False
    
    def get(self):
        while not self.any():
            pass
        return mem32[ self.i2c_base | self.IC_DATA_CMD] & 0xff
    
    if __name__ == "__main__":
        import utime
        from machine import mem32
        from i2cSlave import i2c_slave
        
        s_i2c = i2c_slave(0,sda=0,scl=1,slaveAddress=0x41)
        
        try:
            while True:
                print(s_i2c.get())
            
        except KeyboardInterrupt:
            pass
Nevedeli byste nekdo co s tim? Kdyztak predem diky za pripadne napady.

Řešení dotazu:


Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

Jendа avatar 25.12.2021 23:23 Jendа | skóre: 78 | blog: Jenda | JO70FB
Rozbalit Rozbalit vše Re: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
Odpovědět | | Sbalit | Link | Blokovat | Admin
Potřebuješ logický analyzér, například klon Saleae za $10 z Ali (náhodný výsledek z hledání, žádný affiliate a konkrétní seller neověřen).
26.12.2021 09:50 ehmmm
Rozbalit Rozbalit vše Re: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
Vicemene souhlas. Blbe se hleda chyba, kdyz nevidis, co to vlastne dela nebo nedela.

(Az na to, ze casem nejspis dospejes k tomu, ze to ma byt samostatny pristroj s kroutiky a tlacitky a ne neco, co se strka do USB a ovlada se to mysi.)
Jendа avatar 26.12.2021 10:13 Jendа | skóre: 78 | blog: Jenda | JO70FB
Rozbalit Rozbalit vše Re: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
To mi teda zrovna u logického analyzéru přijde mnohem pohodlnější. Další killer feature uvedeného je efektivně neomezený buffer, až donedávna mívalo všechno nějakou trapnou kapacitu a člověk musel strašně řešit triggery a jak zařídit aby viděl co potřebuje.
26.12.2021 10:23 MarV | skóre: 11
Rozbalit Rozbalit vše Re: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
Jo na log analyzátor je PC UI daleko pohodlnější (větší obrazovka, scroll, zoom) a knoflíkové věci mají obvykle těžce placené dekodéry protokolů.
26.12.2021 11:17 zdenek2008 | skóre: 26
Rozbalit Rozbalit vše Re: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
Diky, prozkoumam. Mozna by se dalo trochu experimentovat i s picem coby analyzerem, koluji ruzne navody:

https://themachineshop.uk/raspberry-pi-pico-logic-analyzer/

https://www.hackster.io/markkomus/using-a-raspberry-pi-pico-as-a-logic-analyzer-with-pulseview-e12543
26.12.2021 10:35 MarV | skóre: 11
Rozbalit Rozbalit vše Re: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
Odpovědět | | Sbalit | Link | Blokovat | Admin
Pokud je čím, tak alespoň zkontrolovat, že fungují pullupy a obě lajny jsou v klidu v log 1 (HiZ). Dále se podívat, zda má master knihovna podporu návratových hodnot, které by osvětlily co ne/funguje (např ACK I2C komunikace). Pokud návratové hodnoty nemá, tak najít lepší knihovnu. Další možností může být použít nejdříve nějaký zaručeně funkční slave, jako třeba jednoduchý teplotní snímač, a na něm ověřit master část.
26.12.2021 11:40 zdenek2008 | skóre: 26
Rozbalit Rozbalit vše Re: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
Příloha:
Je to tak, jedna se o takove uvodni hratky naslepo. Nejdrive jsem zapomnel pripojit pullupy (snad jsem neodkouril dotycne piny), podruhe jsem je pripojil (4K7) podle prilozeneho schematu. Knihovna TinyWireM by mela byt vice overena uzivatelskou verejnosti, udajne je popularni, ale jsou i jine, to jeste vyzkousim. Ten slave skript pro pico je spise takova sazka do loterie z techto diskuzi:

https://forums.raspberrypi.com/viewtopic.php?t=302978

https://forums.raspberrypi.com/viewtopic.php?t=304074

Zatim nemam jiny i2c komponent (alespon ne vedome) na vyzkouseni, to jeste budu muset prozkoumat.
27.12.2021 12:51 trekker.dk | skóre: 72
Rozbalit Rozbalit vše Re: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
Odpovědět | | Sbalit | Link | Blokovat | Admin
Jen tak na okraj, kdybyste to tu ještě někdy potřeboval - "(nepovolena sipka)" je &lt; (<) a &gt; (>)

Jinak k dotazu - neznám tu tinywire knihovnu, ale v kódu, co jste poslal, nevidím žádnou incializaci toho USI - dělá to ta knihovna sama při volání beginTransmission? Jaké to nastaví hodiny, trefíte se to do toho, co dokáže druhá strana přijmout?

Pokud nemáte k dispozici lepší nářadí, připojte si na SCL a SDA LEDku (ideálně přes tranzistor) - moc z toho neuvidíte, ale přinejmenším by měla blikat (při té frekvenci spíš slaběji svítit), když se něco vysílá. (Tj. poznáte aspoň to, že se vůbec něco vysílá)
Quando omni flunkus moritati
27.12.2021 13:05 MarV | skóre: 11
Rozbalit Rozbalit vše Re: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
Ještě by byla možnost navzorkovat komunikaci zvukovkou. Problémy jsou AC vazba, takže to ztratí informací o ustálených hodnotách, a nízká vzorkovací frekvence. Pokud by se ale komunikační frekvence snížila na jednotky až nízké desítky kHz, tak by při 196kS/s něco smysluplného mohlo být vidět.
Jendа avatar 27.12.2021 14:14 Jendа | skóre: 78 | blog: Jenda | JO70FB
Rozbalit Rozbalit vše Re: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
Já bych zkusil rychle číst GPIOčka a doufat že tam něco bude.
27.12.2021 17:11 zdenek2008 | skóre: 26
Rozbalit Rozbalit vše Re: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
Z t85 si generuji na vystupech 0-4 impulzy 64us - 1024us, pri 8MHz vnitrnim citadle. Pri 1MHz citadle musim nastavit nejkratsi impuls 512us a presto je namereny vystup jen kolem tech 64us. Pri nastaveni kratsich intervalu uz prestane mereni rozlisovat a vsechny vystupy ukazuji stejnou hodnotu kolem tech 60us. Merim picem 100 hodnot v intervalech 10us. Zkousel jsem i kratsi, ale tam klesa rozlisovaci schopnost pica. Zde je vystup z konzole Thonny:
>>> %Run pico_analyzer_prubezny_sber.py
inputPin0:|||||||.....||||||....||||||......||||||.......||||||.....||||||.....|||||||....|||||||.......|||||.
inputPin1:....|||||||||..........||||||||..........|||||||||...........|||||||||||............||||||||||......
inputPin2:.......|||||||||||||||||||..................|||||||||||||||||||||....................|||||||||||||||
inputPin3:........|||||||||||||||||||||||||||||||||||||....................................|||||||||||||||||||
inputPin4:.....||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||...........................
Generator impulzu pro t85:
#define PIN_1 0
#define PIN_2 1
#define PIN_3 2
#define PIN_4 3
#define PIN_5 4

unsigned long naposled_aktivni_pin_1 = micros();
unsigned long prodleva_pin_1 = 64;
byte stav_pin_1 = LOW;

unsigned long naposled_aktivni_pin_2 = micros();
unsigned long prodleva_pin_2 = 128;
byte stav_pin_2 = LOW;

unsigned long naposled_aktivni_pin_3 = micros();
unsigned long prodleva_pin_3 = 256;
byte stav_pin_3 = LOW;

unsigned long naposled_aktivni_pin_4 = micros();
unsigned long prodleva_pin_4 = 512;
byte stav_pin_4 = LOW;

unsigned long naposled_aktivni_pin_5 = micros();
unsigned long prodleva_pin_5 = 1024;
byte stav_pin_5 = LOW;




void setup() {
  pinMode(PIN_1, OUTPUT);
  pinMode(PIN_2, OUTPUT);
  pinMode(PIN_3, OUTPUT);
  pinMode(PIN_4, OUTPUT);
  pinMode(PIN_5, OUTPUT);
}

void loop() {
  unsigned long soucasny_cas = micros();

  // Vystup 1
  if (soucasny_cas - naposled_aktivni_pin_1 > prodleva_pin_1)
  {
    if (stav_pin_1 == LOW)
    {
      stav_pin_1 = HIGH;
    }
    else
    {
      stav_pin_1 = LOW;
    }
    digitalWrite(PIN_1, stav_pin_1);
    naposled_aktivni_pin_1 = soucasny_cas;
  }

  
  // Vystup 2
  if (soucasny_cas - naposled_aktivni_pin_2 > prodleva_pin_2)
  {
    if (stav_pin_2 == LOW)
    {
      stav_pin_2 = HIGH;
    }
    else
    {
      stav_pin_2 = LOW;
    }
    digitalWrite(PIN_2, stav_pin_2);
    naposled_aktivni_pin_2 = soucasny_cas;
  }

  
  // Vystup 3
  if (soucasny_cas - naposled_aktivni_pin_3 > prodleva_pin_3)
  {
    if (stav_pin_3 == LOW)
    {
      stav_pin_3 = HIGH;
    }
    else
    {
      stav_pin_3 = LOW;
    }
    digitalWrite(PIN_3, stav_pin_3);
    naposled_aktivni_pin_3 = soucasny_cas;
  }

  
  // Vystup 4
  if (soucasny_cas - naposled_aktivni_pin_4 > prodleva_pin_4)
  {
    if (stav_pin_4 == LOW)
    {
      stav_pin_4 = HIGH;
    }
    else
    {
      stav_pin_4 = LOW;
    }
    digitalWrite(PIN_4, stav_pin_4);
    naposled_aktivni_pin_4 = soucasny_cas;
  }

  
  // Vystup 5
  if (soucasny_cas - naposled_aktivni_pin_5 > prodleva_pin_5)
  {
    if (stav_pin_5 == LOW)
    {
      stav_pin_5 = HIGH;
    }
    else
    {
      stav_pin_5 = LOW;
    }
    digitalWrite(PIN_5, stav_pin_5);
    naposled_aktivni_pin_5 = soucasny_cas;
  }

}
Merici skript pro pico:
from machine import Pin
import time


#led = Pin(25, Pin.OUT)  # setup pin 25 as an output, this is the onboard LED.
inputPin1 = Pin(11, Pin.IN, Pin.PULL_DOWN)  # setup pin 0 as an input with a pull down resistor.
inputPin2 = Pin(12, Pin.IN, Pin.PULL_DOWN)
inputPin3 = Pin(13, Pin.IN, Pin.PULL_DOWN)
inputPin4 = Pin(14, Pin.IN, Pin.PULL_DOWN)
inputPin5 = Pin(15, Pin.IN, Pin.PULL_DOWN)

#Dstore = [[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0]]

Dstore = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
          [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
          [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
          [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
          [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]


#while True:  # create a loop

for i in range(0, 100):
    Dstore[0][i] = inputPin1.value()  # Read the input pin 0
    Dstore[1][i] = inputPin2.value()  # Read the input pin 1
    Dstore[2][i] = inputPin3.value()  # Read the input pin 2
    Dstore[3][i] = inputPin4.value()  # Read the input pin 3
    Dstore[4][i] = inputPin5.value()  # Read the input pin 4
    #time.sleep(1) #1Hz
    #time.sleep_ms(1000) #1Hz
    #time.sleep_us(1000000) #1Hz
    time.sleep_us(10)

    
for i in range(0, 5):  # loop to iterate through the channels
    print("inputPin{}:".format(i), end='')  # print the input pin label
    for j in range(0, 100):  # loop to iterate through the samples
        if Dstore[i][j] == 0:  # check to see if the sample is low
            print(".", end='')  # print _ if it is low
        elif Dstore[i][j] == 1:  # check to see if the sample is high
            print("|", end='')  # print - if it is high
    print()  # print a new line after each channel

#print()  # print a line in between each group of inputs

#led.toggle()  # toggle the LED so we know the code is running.

#time.sleep(1)  # delay for 1 second.
Pokud ted spustim z t85 i2c master skript, mel bych na picu namerit alespon nejake vyzvy ke komunikaci. Pokud se mi podari skloubit na picu i2c slave s tim mericim skriptem, mohl bych monitorovat i2c sbernici mezi obema cipy. Zatim jsem mel trvalou 0 na SCK a trvalou 1 na SDA.
27.12.2021 19:29 zdenek2008 | skóre: 26
Rozbalit Rozbalit vše Re: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
Zjednodusil jsem i2c master skript pro t85 a pripojil na merici skript pica. Na vystupu 0 je SCL, na 2 je SDA, interval mereni signalu je 10us:
>>> %Run pico_analyzer_prubezny_sber.py
inputPin0:|||||||||...|.|||||||||||||.....||||||||||||||.....|||||||||||||.....|||||||||||||.....|||||||||||||
inputPin1:....................................................................................................
inputPin2:.......||.|..||..........|||.|.|............||....||..........|.|.|.|...........|.|.|.|...........|.
inputPin3:....................................................................................................
inputPin4:....................................................................................................
Vnitrni citac t85 nastaven na 8MHz, upraveny skript:
#include <TinyWireM.h>                  // I2C Master lib for ATTinys which use USI

#define PICO_ADDR   0x41 //0x055 zakladni adresa pica

//int led = 3;


void setup(){
  //pinMode(led, OUTPUT);
  //digitalWrite(led, LOW);
  
  TinyWireM.begin();                    // initialize I2C lib
  delay(1000);
}


void loop(){
//   digitalWrite(led, HIGH);
//   delay(1000);
//   digitalWrite(led, LOW);
//   delay(1000);
//   digitalWrite(led, HIGH);
//   delay(1000);
//   digitalWrite(led, LOW);
//   delay(1000);
//   digitalWrite(led, HIGH);
  //delay(1000);
  //digitalWrite(led, LOW);
  //delay(1000);
  Posli_jeden_byte();
  //delay(1000);  
  //delay(.1); //milisekund
  delayMicroseconds(128);
  //Posli_text();
  //delay(1000);
  //delay(.2);
  //delayMicroseconds(256);
}


void Posli_jeden_byte(){
  TinyWireM.beginTransmission(PICO_ADDR);
  TinyWireM.send(0xAB);
  TinyWireM.endTransmission();
}


void Posli_text(){
  TinyWireM.beginTransmission(PICO_ADDR);
  char myString[12] = "Nazdar!";
  for(byte i = 0; i <= strlen(myString); i++)
  {
      TinyWireM.send(myString[i]);
  }
  TinyWireM.endTransmission();
}
Predpokladejme ze knihovna TinyWireM vykazuje nejakou aktivitu (pod rozlisovaci schopnosti meho 'analyzeru'), jeste je treba nejak overit funkcnost slave skriptu pro pico.
Řešení 1× (zdenek2008 (tazatel))
27.12.2021 21:36 zdenek2008 | skóre: 26
Rozbalit Rozbalit vše Re: Pi Pico nevypisuje informace z ATtiny85 pomoci i2c
Vyreseno:
>>> %Run i2cSlave.py
Co je?
Nazdar!
I2C z T85: 78
I2C z T85: 97
I2C z T85: 122
I2C z T85: 100
I2C z T85: 97
I2C z T85: 114
I2C z T85: 33
I2C z T85: 0
I2C z T85: 171
I2C z T85: 78
I2C z T85: 97
I2C z T85: 122
I2C z T85: 100
I2C z T85: 97
I2C z T85: 114
I2C z T85: 33
I2C z T85: 0
I2C z T85: 171
Stacilo zrusit if __name__ == "__main__": ve slave skriptu na picu a prikazy pod tim pouzit primo. Ted uz vicemene zbyva jen poskladat z prijatych cisel poskladat puvodni text. Diky vsem za uzitecne tipy.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.