Supponiamo che io abbia un cavo UTP sulla trentina di metri che mi colleghi un convertitore USB-rs485 ad un max485 sul mio arduino, vorrei usare questa stessa linea per la programmazione dell'ATmega.
Sappiamo che questo standard è un half-duplex, quindi per ricevere devo avere sui pin 2,3 del max uno stato basso e viceversa per inviare..
Ora, il convertitore usb dovrebbe comportarsi così: sto in ascolto->devo inviare qualcosa?allora mi metto in trasmissione->torno di nuovo in ascolto(e lo fa)
Ma non il max montato sull'arduino. O meglio, non se non glielo dico esplicitamente io da codice.
Oltre ad usare lo standard 422 che implementa due linee separate e sempre differenziali per ogni direzione della trasmissione, c'è un modo per raggirare questo problema?
Come faccio a scrivere sul micro che quando lo programmo, se riceve deve impostare a livello basso un determinato piedino e viceversa quando trasmette?
(Sto dando per scontato che quando programmo un ATmega oltre a mandargli dati devo riceverli anche..)
Hai dimenticato che l'Atmega328 in remoto deve essere resettato, altrimenti non può essere avviato il bootloader per ricevere lo sketch dalla seriale e scriverlo in Flash.
Anch io vedo il problema nel reset del Arduino. Il problema del interfaccia per trasmetter i dati é secondario se non risolvi il problema del reset. Ok potresti usare 2 doppini: 1 RX 1 TX e il terzo per il reset.
Spedito il segnale di reset non sarebbe un grosso problema modificare il bootloader affinché commuti la linea 485 in ricezione. Linea che poi verrebbe pilotata normalmente dallo sketch una volta che questo riparte.
sciorty:
Momento,momento,moomeeento
Perciò che idea avete riguardo il fatto che devo alternare lo stato dei 2 pin del max durante la fase di cariamento?
Edit: modificare il bootloader.. e che ci scrivo?
Le istruzioni in C
A parte gli scherzi, che ci vuoi scrivere? Un digitalWrite sul pin a cui hai collegato i 2 pin del Max485 in modo da mettere il chip in ricezione, poi lasci il resto del bootloader inalterato. In questo modo al reset, il bootloader imposta il Max in ricezione e poi riceve lo sketch. Secondo me funziona.
Ma durante la fase di caricamento l'atmega non invia anche dei dati oltre che riceverli? non so, roba tipo handshake.. anche perchè sulla scheda vedo che si accendono entrambi i led!
Per il reset dovrei farcela: mettiamo che la sezione del cavo utp sia 1mm la resistenza è di 19,5ohm/km, e mettendo proprio per assurdo che il pin reset assorba 1A calcolo una caduta sul cavo di 1V e qualcosa.. se non sto sbagliando..
sciorty:
Ma durante la fase di caricamento l'atmega non invia anche dei dati oltre che riceverli? non so, roba tipo handshake.. anche perchè sulla scheda vedo che si accendono entrambi i led!
Sì, devi analizzare il codice dell'Optiboot e modificarlo in modo che ogni volta che deve ricevere o che deve trasmettere sulla seriale venga settato il Max nel corretto stato.
Per il reset dovrei farcela: mettiamo che la sezione del cavo utp sia 1mm la resistenza è di 19,5ohm/km, e mettendo proprio per assurdo che il pin reset assorba 1A calcolo una caduta sul cavo di 1V e qualcosa.. se non sto sbagliando..
sciorty:
Ma durante la fase di caricamento l'atmega non invia anche dei dati oltre che riceverli? non so, roba tipo handshake.. anche perchè sulla scheda vedo che si accendono entrambi i led!
Sì, devi analizzare il codice dell'Optiboot e modificarlo in modo che ogni volta che deve ricevere o che deve trasmettere sulla seriale venga settato il Max nel corretto stato.
Non so proprio dove mettere mani, cioè non so neanche dove risiedano questi codici
Se i miei calcoli erano giusti avrei potuto usare la rs232 anche se tirata per il collo, mi sarei risparmiato i 20 euro del convertitore usbrs485 =(
sciorty:
Per il reset dovrei farcela: mettiamo che la sezione del cavo utp sia 1mm la resistenza è di 19,5ohm/km, e mettendo proprio per assurdo che il pin reset assorba 1A calcolo una caduta sul cavo di 1V e qualcosa.. se non sto sbagliando..
per fortuna c'é sul Arduino sulla USB un fusibile da 0,5A. ] ]
Intorno alla riga 292, metti l'attivazione del chip in ricezione.
// Adaboot no-wait mod
ch = MCUSR;
MCUSR = 0;
if (!(ch & _BV(EXTRF))) appStart();
***************** QUI ************
#if LED_START_FLASHES > 0
Questo punto è buono perché è subito dopo la disattivazione di un eventuale watchdog e subito prima del proseguo del bootloader, dove viene qualche riga più sotto aperta la seriale.
Usa però la manipolazione diretta delle porte logiche, perché altrimenti digitalWrite non funziona (non hai il core Arduino caricato)..
A questo punto, la cosa diventa più maia....
Alla riga 503 c'è la funzinoe putch, che spedisce un byte sulla seriale. Qui dovresti mettere la funzione per attivare il Max in trasmissione.
Alla riga 533 c'è la funzione getch, che riceve un byte. Qui invece devi mettere la funzione per attivare il Max in ricezione.
Stavo vedendo la funzione flash_led, che dovrebbe essere quella che viene ripetuta due volte per segnalare l'inizio di caricamento dello sketch facendo accendere il led13. Pensavo che magari avrei potuto prenderne spunto e semplicemente andare a modificare la porta :
Ma sono solo arrivato a capire che se il micro non è un atmega 8 fa un operazione or tra LED_PIN e la funzione _BV(LED)..
Ma tutta queste variabili cosa contengono? Non trovo le assegnazioni!
Per mettere in input un pin, devi prima vedere dalla piedinatura del microcontrollore a quale porta appartiene e poi imposti il suo bit.
Ad esempio, il pin D10 di Arduino è il piedino PB3, quindi porta "B", bit "3".
Ora, sapendo questo, col link che ti ho dato, vedi che il registro DDx regola la direzione dei pin di una porta.
Quindi se vuoi mettere quel pin come output, devi mettere a 1 il bit 3.
DDRB |= (1<<3);
Adesso lo stato del pin lo regoli con il registro PORTx corrispondente, quindi PORTB.
1 sul bit 3 mette "HIGH" quel pin, 0 lo mette LOW:
PORTB |= (1<<3); //mette HIGH
PORTB &= ~(1<<3); //mette LOW