eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronikaMCP3208 i mikropyton na RPi Pico
Ilość wypowiedzi w tym wątku: 3

  • 1. Data: 2023-07-05 06:54:28
    Temat: MCP3208 i mikropyton na RPi Pico
    Od: Marcin Debowski <a...@I...zoho.com>

    Jakiś czas temu pytałem tutaj o środowisko typu SBC, na którym mógłbym
    sobie coś zmajstrować konkretnego i pouczyć pytona. Wtedy wspominałem o
    kolorymetrii, ale wyszło cos pilniejszego i obecnie próbuję ogarnąć
    obsługę MCP3208 pod ww. RPi (potrzebuje 8-mio kanałowy odczyt
    tenperatury). Tzn. zasadniczo mam z lekka ją ogarnietą, ale dla MCP3008.
    To zasadniczo wygląda tak, że biblioteka do MCP3008 obsługuje bez
    żadnych modyfikacji MCP3208, no ale dostaję wynik 10bit. Czy jakaś dobra
    dusza mogłaby mi trochę powyjasniać, bo tu nie tylko że pyton ale
    jeszcze programowanie cipa dochodzi? Pytania w kodzie.

    Poniżej kod dla mcp3008.py stąd:
    https://blog.rareschool.com/2021/02/raspberry-pi-pic
    o-project-2-mcp3008.html

    import machine

    class MCP3008:

    def __init__(self, spi, cs, ref_voltage=3.3):
    """
    Create MCP3008 instance

    Args:
    spi: configured SPI bus
    cs: pin to use for chip select
    ref_voltage: r
    """
    self.cs = cs
    self.cs.value(1) # ncs on
    self._spi = spi
    self._out_buf = bytearray(3)
    self._out_buf[0] = 0x01
    self._in_buf = bytearray(3)
    self._ref_voltage = ref_voltage

    # co robią te bufory in and out? Rozumiem, że pierwszy bajt coś ustawia,
    # a dwa pozostałe są na dane?

    def reference_voltage(self) -> float:
    """Returns the MCP3xxx's reference voltage as a float."""
    return self._ref_voltage

    def read(self, pin, is_differential=False):
    """
    read a voltage or voltage difference using the MCP3008.

    Args:
    pin: the pin to use
    is_differential: if true, return the potential difference between two
    pins,


    Returns:
    voltage in range [0, 1023] where 1023 = VREF (3V3)

    """

    self.cs.value(0) # select
    self._out_buf[1] = ((not is_differential) << 7) | (pin << 4)
    self._spi.write_readinto(self._out_buf, self._in_buf)

    #kopiuje zawartość out do in?

    self.cs.value(1) # turn off
    return ((self._in_buf[1] & 0x03) << 8) | self._in_buf[2]

    #tu widzę jakieś przesuwania bitów, ale jak wielkość bufora jest bajt to
    #przesunięcie o 8 co daje? A co daje binarne "and" zawartości [1] z
    #00000011? Dostaję 2 młodsze bity, które w połączeniu z [2] dają 10
    #bitów? Jeśli tak to 0x0F powinno z tego zrobić 12bit a jakby nie rozbi
    #- jak podłącze na odpowiedni pin MC3208 3V3 to nadal dostaje 1023, więc
    #ta bitowość może jest gdzies definiowana w "machine"?

    --
    Marcin


  • 2. Data: 2023-07-05 12:58:52
    Temat: Re: MCP3208 i mikropyton na RPi Pico
    Od: "Grzegorz Niemirowski" <g...@g...net>

    Marcin Debowski <a...@I...zoho.com> napisał(a):
    > self._spi = spi
    > self._out_buf = bytearray(3)
    > self._out_buf[0] = 0x01
    > self._in_buf = bytearray(3)
    > self._ref_voltage = ref_voltage
    > # co robią te bufory in and out? Rozumiem, że pierwszy bajt coś ustawia,
    > # a dwa pozostałe są na dane?

    Bufory transmitowane po SPI, jeden na dane do wysłania drugi na dane
    odbierane. W nadawczym ustawiana jest wartość pierwszego bajtu. Pierwszy
    transmitowany bajt zawiera bit startu i bity kontrolne, które wybierają
    kanał oraz określają czy odczyt ma być bezwzględny czy różnicowy. Rozdział 5
    w datasheecie.

    > self._spi.write_readinto(self._out_buf, self._in_buf)
    > #kopiuje zawartość out do in?

    Wysyła zawartość out po SPI, odebrane dane umieszcza w in.

    > return ((self._in_buf[1] & 0x03) << 8) | self._in_buf[2]
    > #tu widzę jakieś przesuwania bitów, ale jak wielkość bufora jest bajt to
    > #przesunięcie o 8 co daje?

    Co Cię obchodzi bufor? To nie w nim jest przesunięcie. Odczytywana jest
    wartość spod indeksu 1 do tymczasowego miejsca w pamięci i tam jest
    przesunięcie. To tymczasowe miejsce zapewne jest co najmniej 16-bitowe.
    Bufor nie jest modyfikowany.

    > A co daje binarne "and" zawartości [1] z
    > #00000011?

    Zerowanie starszych 6 bitów, a zachowanie 2 młodszych bez zmian.

    > Dostaję 2 młodsze bity, które w połączeniu z [2] dają 10
    > #bitów? Jeśli tak to 0x0F powinno z tego zrobić 12bit a jakby nie rozbi
    > #- jak podłącze na odpowiedni pin MC3208 3V3 to nadal dostaje 1023, więc
    > #ta bitowość może jest gdzies definiowana w "machine"?

    Co to jest machine?

    MCP3208 zaczyna wysyłać dane nie w określonym miejscu od początku transmisji
    SPI, jak to zwykle bywa, ale od momentu bitu startu. Ten bit nie musi być
    pierwszym bitem w transmisji. Stąd wychodzi, że to gdzie będą bity danych
    jest trochę płynne i zależy od Ciebie. Zobacz sobie obrazek 6-1. Najpierw
    przez 5 cykli (bitów) lecą zera, potem bit startu, bit trybu, trzy bity
    adresu. Następnie przez 1 bit/cykl nic się nie dzieje. Dopiero potem lecą
    dane. Ponieważ bit startu był w tym miejscu w jakim był, dane zaczynają się
    od połowy drugiego bajtu.

    Zobacz co się dzieje w tym kodzie.
    self._out_buf[0] = 0x01
    Bit startu jest umieszczony na końcu pierwszego bajtu. Czyli po rozpoczęciu
    transmisji leci 7 zer i potem jedynka.
    self._out_buf[1] = ((not is_differential) << 7) | (pin << 4)
    Bity kontrolne. Na najstarszym miejscu, czyli zaraz po bicie startu, jest
    bit trybu. Potem bity kanału.

    Czyli wysyłane jest:
    0000000S TKKK0000

    Układ odpowiada po dwóch cyklach (jeden pusty i jeden zerowy). Czyli co
    mamy?
    0000000S TKKK0000
    00000000 0000P0DD

    Czyli w drugim bajcie masz dwa pierwsze bity odpowiedzi. Są to bity 11 i 10.
    Co się stało jak poszerzyłeś maskę o dwa bity w lewo? Odczytałeś pusty bit i
    zerowy. Cały problem polega na tym, że nie masz czytać wcześniej, ale
    później. Masz wziąć dwa bity z bajtu 1, osiem z bajtu 2 oraz DODATKOWO 2
    bity z bajtu 3. Tylko, że aktualnie nie masz bajtu o indeksie 3, bo
    transmitujesz tylko 3 bajty (indeksy 0 - 2). Musisz wydłużyć transmisję.

    Albo zrobić inaczej: wcześniej wysłać bajt startu:
    self._out_buf[0] = 0x04 #start
    self._out_buf[1] = ((not is_differential) << 1 | (pin >> 2)
    self._out_buf[2] = pin << 6
    I wtedy odczyt:
    return ((self._in_buf[1] & 0x0f) << 8) | self._in_buf[2]

    Ogólnie zamieszanie wynika ze stosowania bitu startu, który jest
    charakterystyczny dla portu szeregowego. W tym układzie to on wyznacza
    początek transmisji a nie opadający /CS. Choć /CS i tak musi najpierw opaść.
    Obrazki dobrze to pokazują.

    I nie trzeba unikać datasheetu. Lektura karty katalogowej nie gryzie, a
    pozwala zaoszczędzić czasu i nerwów.

    --
    Grzegorz Niemirowski
    https://www.grzegorz.net/


  • 3. Data: 2023-07-06 05:34:09
    Temat: Re: MCP3208 i mikropyton na RPi Pico
    Od: Marcin Debowski <a...@I...zoho.com>

    On 2023-07-05, Grzegorz Niemirowski <g...@g...net> wrote:
    > Albo zrobić inaczej: wcześniej wysłać bajt startu:
    > self._out_buf[0] = 0x04 #start
    > self._out_buf[1] = ((not is_differential) << 1 | (pin >> 2)
    > self._out_buf[2] = pin << 6
    > I wtedy odczyt:
    > return ((self._in_buf[1] & 0x0f) << 8) | self._in_buf[2]
    >
    > Ogólnie zamieszanie wynika ze stosowania bitu startu, który jest
    > charakterystyczny dla portu szeregowego. W tym układzie to on wyznacza
    > początek transmisji a nie opadający /CS. Choć /CS i tak musi najpierw opaść.
    > Obrazki dobrze to pokazują.
    >
    > I nie trzeba unikać datasheetu. Lektura karty katalogowej nie gryzie, a
    > pozwala zaoszczędzić czasu i nerwów.

    Wielkie dzięki. Muszę to na spokojnie przetrawic i poeksperymentować. I
    to nie tak, że unikam datasheetu ale rozmawiasz z osobą, która nigdy w
    czymś takim (programowanie ptzrtworników i podobnych) nie robiła, więc
    trochę za duża dziura w wiedzy.

    --
    Marcin

strony : [ 1 ]


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: