Nov 232012
 

Introduzione

Lo scopo di questo articolo è quello di fondere le varie branche di questo blog per approdare in un unico prodotto, ossia ci dedicheremo alla costruzione di un progetto CodeBlocks basato sulle wxwidgets finalizzato all’utilizzo della porta seriale per creare una comunicazione 1wire con il sensore di temperatura ds18b20. Se siete approdati a questo articolo probabilmente avrete compreso quale sia l’argomento e molto probabilmente avrete vagato in rete quanto me per trovare qualcosa di pronto e funzionante ma sarete alla disperata ricerca di un articolo diverso che vi porti sulla retta via. Sia chiaro, il contenuto di questo articolo è piuttosto complesso, ma qui troverete qualcosa di funzionante dalla prima all’ultima riga di codice, senza fare salti mortali fra decine di pdf parzialmente incomprensibili che non fanno altro che farvi impazzire.Una precisazione fondamentale sta nel fatto che il software che andiamo a scrivere permette la comunicazione diretta fra il nostro software ed il sensore 1wire, senza l’utilizzo dei drivers forniti dalla Maximm. Se invece siete alla ricerca di qualcosa di più semplice, basato sull’utilizzo dei drivers forniti dalla casa produttrice, allora siete approdati nel posto sbagliato. Questo articolo è talmente lungo e complesso che ho dovuto dividerlo in più parti. Questa è la prima parte in cui affrontiamo un’analisi abbastanza approfondita del bus 1wire, l’utilizzo della porta seriale per interfacciarsi con esso e la ricerca dei dispositivi collegati sul bus.

Bus 1wire

Purtroppo per comprendere questo articolo risulta fondamentale compredere come avviene la comunicazione fra il master (chi interroga il sensore) ed i dispositivi 1wire. In realtà il “come” è banale visto che si tratta di trasmissioni seriali di bit, il problema più importanti è infatti il “quando” visto che un ruolo fondamentale è dato dalle tempistiche con cui vengono gestiti questi segnali. Il segnale binario può essere dato da valori 0 oppure 1 che dipendono dai valori di tensione assunti: a grosse linee, ma è una semplificazione, quando la tensione è nulla il segnale sarà 0 mentre quando la tensione è massima sarà invece un 1. Nello schema qui vicino possiamo vedere una rappresentazione schematica di tutto ciò: sono rappresentate quattro forme d’onda che rappresentano le basi della comunicazioni 1wire, ossia l’invio di un bit pari a 0, pari a 1, la lettura ed il reset. Avete buone possibilità di aver pensato che questa parte è noiosa, che la potete saltare etc, etc. No! Questa parte è fondamentale, se non la capite vi sarà impossibile comprendere il resto dell’articolo.

Prima di tutto ripetiamo che le comunicazioni 1Wire sono sempre inizializzate dal master e che quest’ultimo può essere un microprocessore, una porta seriale del PC o quel che ci pare, dotato di hardware / software in grado di interagire con i sensori. Ora vediamo la scrittura dei bit 0 e 1: per scrivere 1 il master dapprima porta la tensione a 0 e poi la eleva per il restante periodo. Come vedete dalla figura i periodi suddetti sono scanditi dalle lettere A e B che corrispondono a tempi ben precisi e che rappresentano la chiave di funzionamento di tutto il sistema. A è compreso fra 5 e 15 microsecondi (raccomandati 6) mentre B è superiore a 54 microsecondi (raccomandati 64). Ricapitolando, se un master vuole inviare un bit di valore 1 ad un dispositivo 1wire, deve abbassare a 0 la tensione per un periodo compreso fra 5 e 15 microsecondi, e poi innalzarla per almeno 54 microsecondi. Vi faccio notare che il passaggio fra tensioni massime e minime e viceversa non è istantaneo ma è caratterizzato da una pendenza che nella progettazione dell’hadware di comunicazione riveste una grossa importanza. Se ad esempio l’inclinazione è troppo bassa, potrebbe accadere che il master non riesce a portare a 0 la tensione entro i 15microsecondi per cui diventa impossibile rispettare il periodo “A”. La scrittura di un bit pari a 0 è similare ma con tempistiche molto diverse, infatti prima deve essere ridotta la tensione per un periodo C compreso fra 60 e 120 microsecondi (raccomandati 60) e poi alzata per un periodo D di almeno 8 micorsecondi (consigliati 10).

Nella tabella sottostante un riassunto delle tempistiche.

Segmento MIN Raccomandato MAX
A 5 6 15
B 54 64
C 60 60 120
D 8 10
G 0 0
H 480 480 640
I 63 70 78
J  410  410

Infine, allo stesso modo vediamo anche il reset. All’inizio la linea è impostata a livello alto per un tempo che nella modalità standard è pari a 0 microsecondi. Poi la linea passa ad uno stato basso per un tempo H compreso fra 480 e 640 microsecondi (consigliato 480). A questo punto la resistenza di pullup riporta la linea ad uno stato alto e lo slave dovrà riabassare lo stato della linea entro un tempo I compreso fra 63 e 78 microsecondi (consigliati  70) per poi rilasciarla ad uno stato alto per un tempo complessivo di almeno 410 microsecondi. Capisco che la noia avrà oramai preso piede ma perchè è importante conoscere questi tempi? Con un microprocessore, pic, atmel, o qualunque altro, è molto semplice alzare ed abbassare il segnale sulla linea e attendere le necessarie tempistiche, ma con la porta seriale come facciamo? Con essa non possiamo inviare singoli segnali ma possiamo unicamente inviare un minimo di un byte.

Reset via RS232

Concentriamoci sulla procedura di reset, per ora. Nella modalità standard (ne esiste una overdrive che non affronteremo) il master deve portare ad uno stato basso la linea per 480-640 microsecondi per poi rilasciarla in modo che la resistenza di pullup la porti allo stato alto. Traducendo in binario dobbiamo fare in modo di inviare bits pari a zero per 480 microsecondi e poi “rilasciare” la linea con gli 1. Vi faccio notare che ho sempre parlato di alto e basso senza specificare i voltaggi che nello standard 1wire vanno da 0 a 5V, ma che nella porta seriale vanno tipicamente da -12 a +12, ma anche questo dato non è necessariamente così.

Ora, dopo questa digressione, seguite il ragionamento. Se apriamo la porta seriale a 9600 baud significa che vengono inviati 9600 byte al secondo, ossia un byte in 1042 microsecondi (1041,66…). Ricordiamoci che ogni byte, nella trasmissione seriale, è accompagnato ad un bit di start e stop per cui in totale sono 10 bit ed ogni bit occupa un tempo di 104.2 microsecondi. Nello schema a lato vedete il raffronto tra quella che deve essere la trasmissione seriale per effettuare il reset 1wire e sotto, correlato temporalmente, lo schema con i vari bit. Come potete vedere il segnale viene tenuto basso sino al bit 3 (che è il quarto visto che si contano da zero), più il bit di start (che è sempre a livello basso). In totale sono 5 bits che moltiplicati per 104,2 fanno 521µs, ossia dei maggiori 480µs minimi ed inferiori ai 640µs massimi. Quindi 4bit (il primo è di start per cui hai solo 4 bit di dati) impostati a zero e gli altri posti a uno fanno un bel 00001111 binario. Ora fate molta attenzione: nello schema è riportato che il bit numero zero è il LSB (Less Significant Bit), ossia il bit meno significativo, mentre il numero 7 è il MSB (Most Significant Bit), ossia il meno significativo.Tutto ciò significa che il valore modulato nella trasmissione seriale (00001111 ) è invertito rispetto alla rappresentazione in memoria del numero (su piattaforme Windows – x86). Detto ciò la rappresentazione in memoria (del PC) sarà 11110000 che corrisponde a 0xF0 in esadecimale che è appunto quanto riportato nello schemino qui a lato.

Durante “gli uni” la resistenza di pullup porta la linea a valore alto e a partire fra i 15 e 60µs, lo slave risponde con il “Presence pulse” (impulso di presenza) che dura da 60 a 240µs . Anche se la risposta arriva subito, la porta seriale trascriverà i “bits” letti nel primo byte della risposta subito successiva motivo per cui lo schema qui a lato è molto fuorviante in questo senso, infatti non risulta chiaro come vengono a formarsi i valori di ritorno. La realtà è che ai fini pratici non ha alcuna importanza di quale sia il valore di ritorno, ricordiamoci però che il valore che otteniamo deriva dalla somma dei segnali inviati in contemporanea da tutti i dispositivi 1wire collegati alla porta seriale. Ma tutto ciò ha poca importanza in quanto ci basta sapere che se otteniamo una risposta significa che ci sono dispositivi collegati, altrimenti non c’è ne sono: più facile di così. Riassumendo, per fare il reset dei dispositivi 1wire è sufficiente inviare 0xF0 a 9600baud e se otteniamo una risposta significa che ci sono dispositivi collegati che hanno risposto alla richiesta di reset, in caso contrario non ci sono dispositivi collegati.

Write bit

Ora che abbiamo visto come eseguire il reset, passiamo alla scrittura dei singoli bit, poi vedremo a cosa ci serve. Come facciamo ad inviare un singolo bit pari a 0 o 1? Nello schema qui sotto vediamo una ripetizione, più dettagliata della precedente che illustra i timing della comunicazione. Come vediamo dalla figura a lato la  la scrittura di un bit alto (1) o basso (0)  comincia in entrambi i casi con il portare la linea ad un livello basso. Successivamente se scriviamo un bit=1 la linea viene rilasciata e portata ad uno stato alto dalla resistenza di pullup, viceversa nella scrittura di un bit=0 la linea viene mantenuta allo stato basso per un tempo molto più lungo. Anche in questo caso perciò la conoscenza dei tempi è fondamentale. Nel primo caso (write 1) la linea è portata ad uno stato basso per un tempo compreso fra 5 e 15µs (consigliati 6), mentre per il secondo caso fra 60 e 120 (consigliati 60).  Come vedete stiamo parlando di tempi marcatamente più corti di quelli della procedura di reset (480µs e 640µs).

Ora mettiamo il caso che vogliamo scrivere un bit=1. Dobbiamo portare la linea ad un livello basso per un tempo compreso fra 5 e 15 µs, ma se utilizzaziomo la porta seriale a 9600baud, l’impulso minimo è di 102,4µs per cui la cosa fondamentale da fare è aumentare la velocità della porta seriale che dobbiamo portare a 115200 baud. In questo modo, sempre tenendo conto dei bit di start e stop, inviamo un singolo bit in 8.68µs. Questo bit però ricadrà sul bit si start (sempre a livello basso) e tutto il resto sarà a livello alto per cui per scrivere un bit pari a 1 inviamo 8 bit a livello alto, ossia 0b11111111 ossia 0xFF. Allo stesso modo per inviare un bit pari a 0 dobbiamo tenere la linea bassa per tutta la durata del byte, infatti così facendo inviamo un impulso di 78.12µs (8bit + bit di start) che rientrano nel range 60-120. Per questo motivo per inviare un bit 1-wire pari a 0, inviamo 0b00000000 ossia 0x00 sulla porta seriale. Nella realtà, anzichè usare un totale di 9 bit, potremmo usarne solo 8 per un totale di 69.4µs che rientrano ancora nel range e, anzi, si avvicinano di più al valore consigliato di 60µs. Facendo ciò l’ultimo bit (7, il più significativo), sarà posto a 1 per cui otteniamo un valore esadecimale di 0x80. C’è però un rovescio della medaglia: mentre se usiamo 0xFF e 0x00 è intuitivo capire che inviamo i bit 1 e 0 rispettivamente, con valori di 0xFF e 0x80 la cosa è meno scontata.

Sotto vi riporto le immagini con i grafici che riportano la linea 1wire raffrontata con i bit della porta seriale.

m

Ovviamente oltre  inviare bit, ci sono casi in cui li dobbiamo leggere dal dispositivo 1-wire. Se avete capito i passaggi precedenti non c’è niente di nuovo. Dobbiamo prima comunicare al dispositivo che siamo pronti alla lettuara scrivendo un “bit 1” che abbiamo visto si fa infiando 0xFF. A questo punto lo slave, ossia il dispositivo,risponde mantenendo dapprima la linea allo stato basso per un certo tempo per poi rilasciarla. Il tempo con cui la line viene tenuta bassa determina se il bit deve essere interpretato come un uno o uno zero. Visto che oramai abbiamo capito i concetti che legato i timing 1wire e i valori che otteniamo sulla porta seriale, ci soffermiamo a guardare i grafici che vi ho riportato qui sotto. Veidamo che nel caso di bi1 riceviamo un valore fisso di 0xFF mentre per bit=0 la risposta può variare da 0xFE sio a 0x00.

Per ora abbiamo visto una parte che oltre ad essere un po’ complessa, non viene mai esaurientemente spiegato nei vari tutorials che trovate in rete. Ora andiamo ad affrontare un secondo argomento, altrettanto complesso, ma che a differenza del primo è molto ben documentato in rete anche se non ho trovato tutorials specifici per l’utilizzo della RS232 se non a livello astratto, senza scendere nei dettagli che sono quelli che poi permettono al nostro progetto di funzionare.

1-wire rom search

Prima di studiare la soluzione, cerchiamo di spiegare quel’è il problema. Facciamo un semplice esempio chiarificatore. Abbiamo il nostro PC e tramite la nostra rs232 abbiamo collegato una semplice rete composta da 3 sensori. Come facciamo ad identificare un sensore piuttosto che un’altro? Come facciamo a leggere la temperatura del sensore 1 piuttosto che il 3? Pare ovvio che indipendentemente dal tipo di bus, ogni dispositivo deve avere un suo identificativo univoco che permette di distinguere il sensore 1 dal 2 dal 3. Ci sono diverse soluzioni per risolvere questo problema, ad esempio si protebbero usare dei dip-switch sui dispositivi per selezionare un identificativo, si potrebbe usare identificativi univoci impostati in fabbrica, si potrebbero impostare valori via software, in questo caso collegando in una prima fase i dispositivi uno ad uno singolarmente impostando l’indirizzo per poi spostarlo nel resto della rete. Nel caso dei dispositivi 1wire gli indirizzi univoci sono scritti nella rom del dispositivo, impostati in fabbrica per cui non sono modificabili. Ma come facciamo a leggerli? La cosa più semplice da pensare è che ci sia un comando da inviare e quando il dispositivo riceve quel comando invia la sua ROM. Effettivamente questo comando esiste, ma è possibile utilizzarlo solamente se nella rete 1wire è collegato un solo dispositivo alla volta. Questo è abbastanza logico. Se voi inviate il comando per leggere il codice della ROM, tutti i dispositivi collegati risponderanno in contemporanea per cui quello che andiamo a leggere non è altro che la somma degli impulsi seriali inviati da tutti i dispositivi in contemporanea. Allora come facciamo?

La ROM 1wire e l’algoritmo di ricerca.

Prima di vedere l’algoritmo di ricerca vediamo com’è fatto il codice identificativo di ogni dispositivo. Probabilmente avete già visto l’immagine qui a lato. Vediamo cheil codice identificativo è composto da 64 bit. Gli otto meno significativi contengono 8bit, ossia 1byte, per l’identificazione del tipo di dispositivo; seguono 48 bit che esprimono un numero progressivo univoco e per finire ci sono 8 bit di CRC, ossia un codice di controllo che permette di verificare la correttezza dei restanti bit e che è necessario ricalcolare nell’algoritmo di ricerca per essere certi che il valore ottenuto sia realmente corretto.

Per cominciare la ricerca dobbiamo innanzitutto inviare un comando di reset, e questo abbiamo visto come si fa. La seconda fase consiste nell’ inviare il comando di ricerca. Non esiste un solo comando di ricerca, ma quello che ci interessa è 0xF0. A questo punto facciamo una precisazione importante: nella porta seriale non dobbiamo inviare 0xF0 così com’è ma dobbiamo inviare i singoli bit (11110000) come abbiamo visto nel capitolo precedente, inviandoli dal meno significativo al più significativo (00001111). Se, come detto precedentemente, inviamo 0xFF per i bit pari a 1 e 0x00 per quelli pari a 0, la sequenza da inviare sarà 0x00 0x00 0x00 0x00 0xFF 0xFF 0xFF 0xFF. Un’altra cosa importante da sapere è che quando inviamo i singoli bit 1wire (che sono byte seriali) non è fondamentale che fra l’uno e l’altro vi sia una continuità temporale per cui non dobbiamo fare salti mortali per ottimizzare il software al fine di annullare eventuali piccoli ritardi fra l’invio di un bit e l’altro, motivo per cui possiamo tranquillamente creare una funzione che invia i singoli bit e che viene richiamata più volte dall’esterno: la chiamata alla funzione, l’inizializzazione delle variabili e quant’altro non andrà ad inficiare i timing della trasmissione.

Ora fate molta attenzione perché comincia la parte più complessa. Cosa fanno i dispositivi quando ricevono il comando di ricerca? Tutti i dispositivi inviano in contemporanea il primo bit, ossia il meno significativo, dell’identificativo presente nella loro ROM. Ciò significa che il segnale elettrico che scorre nella porta seriale sarà determinato dalla somma dei segnali di tutti i dispositivi. In realtà è abbastanza semplice da capire, se un dispositivo manda una corrente e un’altro no, la somma sarà la presenza di una corrente, non è complesso da capire (and logico). Subito dopo la lettura da parte del master, gli slave inviano un secondo bit tutti in contemporanea che è il complemento di quello prima inviato, ossia se prima avevano inviato 1 ora inviano 0 e viceversa. A prima vista questa cosa non serve a nulla, ma vedremo fra poco che non è assolutamente così. Visto che avevamo cominciato a pensare ad un esempio con 3 sensori, inventiamoci dei valori di ROM che riportiamo direttamente in binario, per semplicità non userò tutti i 64 bit.

Sensore bit 3 bit 2 bit 1 bit 0
1 0 1 0 1
2 0 0 0 1
3 1 1 0 1

Ora fate molta attenzione. Se i 3 dispositivi inviano il bit meno significativo (bit 0) tutti insieme i tre sensori invieranno in contemporanea i bit 1 1 1 rispettivamente per i sensori 1 2 3.  Un valore 1 corrisponde a lasciare il segnale alto e la somma dei tre non modifica le cose, ossia il segnale resta alto. Ma se non ci fossero dispositivi a rispondere cosa cambierebbe? Niente, infatti l’assenza di dispositivi sulla rete 1wire lascerebbe il segnale alto e non sarebbe distinguibile dal una risposta di bit pari a 1. E’ proprio per per questo motivo che successivamente viene inviato il complemento del bit precedente. Se la risposta resta sempre 1 significa che nessuno sta rispondendo sulla rete, ma nel nostro caso i nostri sensori risponderanno 0 0 0 per cui otteniamo una somma pari a 0 ed il master saprà che tutti i dispositivi che hanno risposto hanno nel primo bit il valore 1.

A questo punto il master invia un bit agli slave, siamo noi in base all’algoritmo che vogliamo implementare a decidere se impostarlo a 1 oppure a 0. Se gli slave riconoscono che il bit appena ricevuto dal master corrisponde a quello poco prima da loro inviato, allora procedono al processo di ricerca, in caso negativo vanno in uno stato di attesa fino al reset successivo. Se nel nostro esempio il master invia il bit 1 (visto che è già a conoscenza che sono tutti impostati a 1) i dispositivi attendono il prossimo comando per inviare il secondo bit, altrimenti passano ad uno stato di attesa per cui alla prossima richiesta da parte del master non risponderà nessuno. Faccio perciò finta di inviare l’1. Gli slave sanno di dover rispondere vista la corrispondenza dei bit e attendono la richiesta del master. Il master richiede la lettura del secondo bit (bit1) e tutti i dispositivi rispondono 0 (tutti e tre i dispositivi hanno il bit 1 impostato a 0) e dopo la lettura da parte del master inviano il complemento che sarà 1. Anche in questo casto caso il master capirà che tutti i valori sono posti a 0 per cui in due passaggi ha scoperto gli ultimi due bit di tutte le rom. A questo punto il master vuole far partecipare tutti i dispositivi col bit1 impostato a 0 ed invia un bit=0 così gli slave continuano a partecipare.

Al terzo ciclo, alla richiesta di lettura, gli slave inviano rispettivamente 1,0,1. L’unico che “modifica” lo stato della linea è lo 0 per cui il risultato complessivo sarà uno zero. Dopo la lettura gli slaves inviano il complemento che sarà 0,1,0 che sommato darà di nuovo zero. In questo caso il master saprà che ci sono bit sia contenenti 1 che zero e deve prendere una decisione in quanto qui si apre un bivio. In questo istante deciderà se far partecipare gli 1, ma poi, per completare l ricerca, dovrà ricominciare da zero e a questo bivio fare la ricerca opposta. Se ora il master invia 0, i dispositivi 1 e 3 sapranno che il loro bit non corrisponde a quello inviato dal master e si mettono in uno stato di attesa e alla lettura successiva risponde solo il sensore 2 che invia prima lo 0 e poi il complemento 1.

Finito di rilevare questa rom il master effettua un reset e ricordandosi il bivio al terzo bit questa volta non invierà lo zero ma l’1, per cui all’ultimo step partecipano i sensori 1 e 3 mentre il 2 resta in attesa. Questo meccanismo di ricerca ad albero permette dopo diversi passaggi di scoprire tutti i codici univoci delle rom degli slave collegati alla rete 1wire. Non resta che ricalcolare il CRC per verificare che non ci siano stati errori nella lettura.

Spero che la spiegazione sia chiara perchè non è per niente semplice spiegare un algoritmo di questo tipo. Nel prossimo articolo passiamo dalla teoria alla pratica. Vediamo come implementare le semplici funzioni che inviano e ricevono dati sulla porta seriale, il tutto, per coerenza con il resto del blog, utilizzando CodeBlocks e le librerie wxWidgets. Per la porta seriale sarà necessario utilizzare una libreria esterna che purtroppo non è disponibile per Mac, motivo per cui la soluzione funziona solamente per Windows e Linux.

  5 Responses to “RS232: interagire con il bus 1wire”

  1.  

    La guida è molto carina. Ho però delle domande a riguardo:
    1- gli slave in genere non rispondono contemporaneamente, giusto?
    2- quando i 3 dispositivi inviano LSB, il segnale non rimane alto, il bus viene prima messo a 0 per circa 15us e poi riportato in alto no? Questo significa che in assenza di slave, il master non vedendo dei fronti di discesa, “capisce” che non c’è nessuno sul bus.

    Precisazione: l’and logico è una moltiplicazione di segnali, non una somma.

    •  

      Intanto ti rinrazio per il commento. Per quanto riguarda le tue domande:
      1)
      Si dici bene. Gli slaves rispondono in contemporanea SOLO quando viene eseguita la ricerca delle ROM. In tutti gli altri casi il master invia una richiesta specifica ad uno specifico slave indicando il numero della ROM per cui risponde SOLO quello specifico slave e non è possibile fare interrogazioni in contemporanea.
      2)
      Ho riletto con molta attenzione quanto ho scritto ed ho trovato alcuni piccoli errori che potevano creare confusione per cui ho fatto delle correzzioni. Ciò a cui ti riferisci è la procedura di reset del bus. Cerco di farti un breve riassunto usando parole semplici: il master (PC, micro, etc) invia sulla porta seriale i primi 4 zeri che portano il segnale in basso. Dopodichè, sempre il master manda degli uni che fanno risalire il segnale in un tempo che varia da 15 a 60 microsecondi (in relazione a quanti sensori sono collegati, tipo e lunghezza del cavo, etc). A questo punto gli slaves rispondono tutti insieme inviando un impulso di presenza (inviano uno zero che abbassa il segnale), per una durata di 60-240 micorsecondi. Il “mescolamento” di questi segnali determina il valore letto in ritorno sulla seriale, MA, come hai detto correttamente, ci basta sapere che se non otteniamo nessuna risposta non ci sono dispositivi, altrimenit si, c’è ne sono! Tra le altre ho volutamente evitato di far notare che nello schema ufficiale c’è scritto che i valori di ritorno sono compresi fra 0x10 e 0x90 in quanto io ottengo mediamente valori più elevati (normalmente 0xE0).
      3)
      Perchè dici ciò? Magari hai ragione tu ma non mi risulta sia una “moltiplicazione”. Hai forse qualche link da passarmi in proposito?

      Sper di essere stato chiaro ed esaustivo, in caso contrario riscrivimi pure, mi fa’ molto piacere confrontarmi con gli altri, altrimenti non perderei tempo a scrivere questi articoli che, credimi, mi portano via tante notti insonni 🙂

  2.  

    Ciao! Complimenti per l’articolo!
    Vorrei chiederti (so che la domanda è banale) ma non ho ben capito cosa intendi per slave e per resistor pull-up. Ho capito che il master è chi interroga il sensore (arduino o pc), lo slave dovrebbe essere il sensore stesso? e il resistor pull-up è interno al sensore?
    Ti ringrazio molto
    Alessandro

    •  

      Ciao.
      Quando si parla di comunicazioni master / slave, si intende che c’è un dispositivo che gestisce la connessione (master) e uno o tanti altri (slave) che rispondono quando interrogati. Il master decide cosa fare e quando mentre gli slave (schiavi) sono i dispositivi che possono solo rispondere al master. Uno slave per essere tale può rispondere SOLO se lo chiede il master altrimenenti non sono autorizzati ad inviare dati. Nel caso specifico il master può essere un PC, quindi il software sul PC tramite la porta seriale andrà a richiede ad uno specifico slave di dirgli “ehi, che temperatura leggi?”. A quel punto lo slave (nel nostro caso il sensore) è autorizzato a rispondere ed inviare al master il dato di temperatura letto. Ma se il master non richiede nulla, lo slave NON può decidere di inviare la temperatura al master in modo autonomo. In caso contrario si parla di connessione multimaster, ossia tutti sono master e possono decidere quando iniziare una trasmissione dati, cosa che complica non poco le cose.
      Per quanto riguarda la resistenza di pullup, questa non è altro che una resistenza posta fra una l’alimentazione ed una linea nella quale ci sono segnali digitali. Quando i dispositivi impiegati nella trasmissione non inviano nulla, la resistenza connessa all’alimentazione mantiene il segnale “alto”, in contrapposizione alla resistenza di pulldown che fa l’opposto ossia mantiene il segnale basso. Queste resistenze vengono appunto usate per mantenere lo stato di una linea in uno stato determinato quando sono “a riposo”. Dove stia la resistenza di pullup dipende dal fatto che si usi un PC piuttosto che un microcontrollore, si usi l’alimentazione attiva o passiva. Comuqne, diciamo che si trova “lungo l’interfaccia di comunicazione”, può stare vicino al sensore (ma non è inclusa in esso) o vicino alla porta seriale, non ha importanza, basta che connetta la linea dati all’alimentazione. Ovviamente la mia è una super-sintesi, ma spero ti chiarisca le idee.