Arduino Forum

International => Italiano => Software => Topic started by: PM68 on Jun 05, 2018, 01:54 pm

Title: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 05, 2018, 01:54 pm
Ciao a tutti,
sono un novizio di Arduino e non ho nessuna base di informatica. Ho bisogno di un grosso aiuto.
Devo comandare una ventola PWM leggendo i comandi da una rete LIN Bus.
Ho trovato qui sul forum un codice che legge la LIN BUS, ho identificato i numeri che corrispondono alla velocità della ventola e il codice che fa girare le ventole a 3 velocità.

Dovrei mettere assieme le due cose:

-quando legge sulla LIN il n° 76 comandare la ventola al 75% PWM
-quando legge sulla LIN il n° 75 comandare la ventola al 50% PWM
-quando legge sulla LIN il n° 74 comandare la ventola al 25% PWM
-quando legge sulla LIN il n° 7F la ventola è ferma

Il codice originale che utilizzo per leggere la LIN con un Arduino DUE l'ho preso dalla discussione "LIN Bus communication Uno to Due".
Il codice per comandare la ventola l'ho preso dall'esempio della libreria "pwm01.h".
Di seguito il codice ibrido che ho messo assieme con scarsi risultati. Come ho anticipato non ho basi di informatica.

Code: [Select]

//  CODICE PER RILEVAZIONE EVENTI SU LINBUS e COMANDO VENTOLE
//Due project, Receive

#include <SerialSniffer.h>
#include <lin_stack.h>
#include <pwm01.h>

const int PIN_TXE = 18;
const int PIN_CS = 2;
word VentPin = 3;

uint8_t rxByte[4];

void setup() {

  pinMode(PIN_CS, OUTPUT);
  pinMode(VentPin, OUTPUT);
  digitalWrite(PIN_CS, HIGH);
  pwm25kHzBegin();

  Serial1.begin(9600, SERIAL_8E1); //LIN Serial Rx, 8E1 is BMW iBus standard
  //Serial.begin(9600); //debug serial
  //Serial.println("Due debug Comms");

  delay(100);
}

void loop() {
  while (Serial1.available()) {
    delay(5);
    byte actuallyRead = Serial1.readBytes(rxByte, 8); //Read UP TO 8 bytes
    if (actuallyRead > 0)
    {
      for (uint8_t i = 0; i < actuallyRead; i++)
      {
        Serial.println(rxByte[i], HEX);
      }
    }
    if (rxByte == 74)
    { pwmDuty(59); // 75% (range = 0-79 = 1.25-100%)
      delay (5000);
    }
    if (rxByte == 75)
    { pwmDuty(39); // 50% (range = 0-79 = 1.25-100%)
    delay (5000);
    }
    if (rxByte == 76)
    { pwmDuty(19); // 25% (range = 0-79 = 1.25-100%)
    delay (5000);
    }
   
  }

  void loop() {
    pwmDuty(19); // 25% (range = 0-79 = 1.25-100%)
    delay(5000);
    pwmDuty(39); // 50% (range = 0-79 = 1.25-100%)
    delay (5000);
    pwmDuty(59); // 75% (range = 0-79 = 1.25-100%)
    delay (5000);
  }

  void pwm25kHzBegin() {
    TCCR2A = 0;                               // TC2 Control Register A
    TCCR2B = 0;                               // TC2 Control Register B
    TIMSK2 = 0;                               // TC2 Interrupt Mask Register
    TIFR2 = 0;                                // TC2 Interrupt Flag Register
    TCCR2A |= (1 << COM2B1) | (1 << WGM21) | (1 << WGM20);  // OC2B cleared/set on match when up/down counting, fast PWM
    TCCR2B |= (1 << WGM22) | (1 << CS21);     // prescaler 8
    OCR2A = 79;                               // TOP overflow value (Hz)
    OCR2B = 0;
  }

  void pwmDuty(byte ocrb) {
    OCR2B = ocrb;                             // PWM Width (duty)
  }
Title: Re: Comandare ventola PWM con LIN BUS
Post by: gpb01 on Jun 05, 2018, 02:01 pm
... beh ... usa una semplice struttura switch/case (https://www.arduino.cc/reference/en/language/structure/control-structure/switchcase/) e assegni il valore del PWM in funzione del valore LIN ricevuto :)

Guglielmo
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 06, 2018, 01:36 pm
Grazie Guglielmo!
Sembra perfetta per quello che devo fare.
Questa sera provo.

Mauro
Title: Re: Comandare ventola PWM con LIN BUS
Post by: gpb01 on Jun 06, 2018, 02:28 pm
>PM68:   ti ricordo che in conformità al regolamento (http://forum.arduino.cc/index.php?topic=149082.0), punto 7, devi editare il tuo post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More -> Modify che si trova in basso a destra del tuo post) e racchiudere il codice all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 07, 2018, 11:56 pm
Grazie Guglielmo per le istruzioni.
Avevo cercato di inserire il codice correttamente ma non ci sono riuscito.
Ora ci riprovo.

Ho modificato il codice inserendo la struttura switch case come mi hai suggerito però mi da questo errore che mi sembra avere capito dipende dalla costante inByte che ho provato a mettere "char" invece di "int" ma non gli piace:
 
Code: [Select]

jump to case label [-fpermissive]
 


 Il mio codice è questo:
 
Code: [Select]

//  Arduino DUE
//  CODICE PER RILEVAZIONE EVENTI SU LINBUS  e COMANDO VENTOLE

#include <SerialSniffer.h>
#include <lin_stack.h>
#include <DuePWM.h>

#define PWM_FREQ1  20000
#define PWM_FREQ2  20000

DuePWM pwm( PWM_FREQ1, PWM_FREQ2 );
#define PIN_TXE 1
#define PIN_CS 2
#define FAULT_PIN 9
uint8_t rxByte[4];

void setup() {
  pinMode(PIN_CS, OUTPUT);
  pinMode(FAULT_PIN, OUTPUT);
  digitalWrite(PIN_CS, HIGH);
  digitalWrite(FAULT_PIN, HIGH);
  Serial1.begin(9600, SERIAL_8E1); //LIN Serial Rx, 8E1 is BMW iBus standard
  pwm.setFreq1( PWM_FREQ1 );
  pwm.setFreq2( PWM_FREQ2 );
  pwm.pinFreq1( 6 );  // Pin 6 freq set to "pwm_freq1" on clock A
  pwm.pinFreq2( 7 );  // Pin 7 freq set to "pwm_freq2" on clock B
}

void loop() {
  if (Serial1.available() > 0) {
    char inByte = Serial1.read();

    switch (inByte) {
      case '74': //quando legge "74" sulla serial1
        uint32_t pwm_duty = 190; // 75% duty cycle
        pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 12
        break;
      case '75': //quando legge "75" sulla serial1
        uint32_t pwm_duty = 127; // 50% duty cycle
        pwm.pinDuty( 6, pwm_duty );  // 50% duty cycle on Pin 12
        break;
      case '76': //quando legge "76" sulla serial1
        uint32_t pwm_duty = 63; // 25% duty cycle
        pwm.pinDuty( 6, pwm_duty );  // 25% duty cycle on Pin 12
        break;
      case '7F': //quando legge "7F" sulla serial1
        pwm.stop(6);
        break;

    }
  }
}
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 08, 2018, 02:25 pm
Ho risolto, mancavano alcune parentesi graffe.
Title: Re: Comandare ventola PWM con LIN BUS
Post by: gpb01 on Jun 08, 2018, 02:40 pm
Mmm ... sicuro di quei "case" ? ? ?

inByte conterrà, dopo la lettura dalla seriale 1 byte (1 carattere) mentre tu stai facendo dei "case" con un insieme di due caratteri (es. '7F', ovvero un numero a 16 bit).

Ho invece idea che tu devi confrontare, visto i numeri che indichi, con valori esadecimali, che si rappresentano con lo 0x davanti ovvero 0x74, 0x75, 0x76 e 0x7F che occupano 1 byte (1 carattere) come tu ricevi.

Guglielmo
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 09, 2018, 12:39 am
Grazie di tutti i consigli Guglielmo, ho corretto.
Ora volevo provarlo dandogli i comandi da monitor seriale, ho cambiato da "Serial1" a "Serial" ,  non mi da nessun errore di compilazione, però la ventola parte alla massima velocità e qualsiasi cosa scrivo sul monitor seriale non cambia niente. Ho provato a scrivere sia 74 che 0x74 o 7F o 0x7F inoltre essendo di default "pwm.stop" mi aspetto che se non do comandi dovrebbe stare ferma.
Mi puoi dire cosa sbaglio?
Code: [Select]

#include <DuePWM.h>

#define PWM_FREQ1  20000
#define PWM_FREQ2  20000
char inByte ;

DuePWM pwm( PWM_FREQ1, PWM_FREQ2 );

void setup() {

  Serial.begin(9600);
  pwm.setFreq1( PWM_FREQ1 );
  pwm.setFreq2( PWM_FREQ2 );
  pwm.pinFreq1( 6 );  // Pin 6 freq set to "pwm_freq1" on clock A
  pwm.pinFreq2( 7 );  // Pin 7 freq set to "pwm_freq2" on clock B
}

void loop()
{
  if (Serial.available() > 0)
  {
    inByte = Serial.read();
    switch (inByte)
    {
      case 0x74: //quando legge "74" sulla serial1
        { uint32_t pwm_duty = 190; // 75% duty cycle
          pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
          delay (5000);
          break;
        }
      case 0x75: //quando legge "75" sulla serial1
        { uint32_t pwm_duty = 127; // 50% duty cycle
          pwm.pinDuty( 6, pwm_duty );  // 50% duty cycle on Pin 6
          delay (5000);
          break;
        }
      case 0x76: //quando legge "76" sulla serial1
        { uint32_t pwm_duty = 63; // 25% duty cycle
          pwm.pinDuty( 6, pwm_duty );  // 25% duty cycle on Pin 6
          delay (5000);
          break;
        }
      case 0x7F:
        { pwm.stop( 6 );
          delay (5000);
          break;
        }

      default:
        {
          pwm.stop( 6 );
        }
    }
  }
}
Title: Re: Comandare ventola PWM con LIN BUS
Post by: gpb01 on Jun 09, 2018, 03:36 pm
Che semplicemente NON puoi usare il monitor seriale ...
... il monitor seriale invia quello che scrivi in ASCII e qiuindi, se scrivi 74, NON invia il codice 0x74, ma invia DUE caratteri ASCII uno per il 7 che è 0x37 ed uno per il 4, che è 0x34. Idem per il resto.

Se vuoi usare il monitor seriale, devi temporaneamente modificare il codice è mettere, al posto di quei codici esadecimali, ad esempio delle lettere ... 'A', 'B', 'C', 'D' ... così quando premi una lettera viene inviata solo quella e riesci a leggerla ;)

Guglielmo
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 09, 2018, 05:58 pm
Sei un grande Guglielmo! Con la seriale funziona.

Ora lo provo nella vecchia versione collegato alla LIN dell'auto.

Grazie
Mauro

Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 17, 2018, 04:17 pm
Buongiorno a tutti,
proseguendo con i miei rilievi mi sono accorto che i frame che rilevavo sulla lin bus non erano completi perchè la velocità di trasmissione non è 9600 ma 19200.
Corretto il tutto i codici che attivano le ventole sono formati da più byte e inseriti nel mio codice mi da un errore di sintassi:"expected ':' before numeric constant".
Mi potete aiutare per la scrittura corretta? Di seguito il mio codice:

Code: [Select]


//  CODICE PER RILEVAZIONE EVENTI SU LINBUS LEXUS e COMANDO VENTOLE PWM

#include <DuePWM.h>

#define PIN_TXE 18
#define PIN_CS 2
uint8_t rxByte[8];

#define PWM_FREQ1  20000
#define PWM_FREQ2  20000
uint32_t pwm_duty = 0;
byte inByte;

DuePWM pwm( PWM_FREQ1, PWM_FREQ2 );

void setup() {
  pinMode(PIN_TXE, OUTPUT);
  pinMode(PIN_CS, OUTPUT);
  digitalWrite(PIN_TXE, HIGH);
  digitalWrite(PIN_CS, HIGH);
  Serial1.begin(19200, SERIAL_8E1); //LIN Serial Rx, 8E1 is BMW iBus standard
  pwm.setFreq1( PWM_FREQ1 );
  pwm.setFreq2( PWM_FREQ2 );
  pwm.pinFreq1( 6 );  // Pin 6 freq set to "pwm_freq1" on clock A
  pwm.pinFreq2( 7 );  // Pin 7 freq set to "pwm_freq2" on clock B
}

void loop()
{
  if (Serial1.available() > 0)
  {
    inByte = Serial.read();
    switch (inByte)
    {
      case 0x0 0x60 0xFE 0x0: //quando legge la sequenza "0 60 FE 0" sulla seriale
        { pwm_duty = 60; // 75% duty cycle
          pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
          break;
        }
      case 0x0 0x66 0xFE 0x0: //quando legge la sequenza "0 66 FE 0" sulla seriale
        { pwm_duty = 130; // 50% duty cycle
          pwm.pinDuty( 6, pwm_duty );  // 50% duty cycle on Pin 6
          break;
        }
      case 0x0 0x78 0xFE 0x0: //quando legge la sequenza "0 78 FE 0" sulla seriale
        { pwm_duty = 200; // 25% duty cycle
          pwm.pinDuty( 6, pwm_duty );  // 25% duty cycle on Pin 6
          break;
        }

      default:
        { pwm_duty = 255; // 0% duty cycle
          pwm.pinDuty( 6, pwm_duty );  // 0% duty cycle on Pin 6
          break;
        }
    }
  }
}
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Patrick_M on Jun 17, 2018, 04:51 pm
lo switch confronta 1 numero  (int o char) quindi confronta il valore attuale di inByte che non può essere contemporaneamente 0 60 fe 0 che sono 4 byte
inoltre la sintassi del case non prevede quella scrittura



Title: Re: Comandare ventola PWM con LIN BUS
Post by: gpb01 on Jun 17, 2018, 04:54 pm
Il while/case vuole UNA sola costante numerica, quindi scordati una sitassi come quella che hai scritto.

Secondo me, la strada più semplice e rivecere dalla seriale in una "macchina a stati finiti" in cui avanzo nei vari "stati" mano mano che ricevo i byte corretti e, quando una sequenza è stata completamente identificata, faccio quello che devo fare.

Guglielmo

P.S.: Patrick_M mi ha parzialmente anticipato. :)
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 20, 2018, 12:26 am
Grazie del suggerimento, mi sono documentato su cosa vuol dire "macchina a stati finiti" e mi sono guardato parecchi esempi però sono bloccato.

Diciamo che il mio primo stato è il codice che rileva dalla Lin Bus una "sbrodolata" di byte concatenati. Qui sotto li ho incolonnati per chiarezza partendo dal 66 66 :

66 66 9E 0
66 66 78 1E 0 1E 0 E0 0 E0 0 0 FE E6 0 0 E0 0
66 66 E0 1E 0 6 60 80  18 18 60 86 0 0
66 66 9E 0 1E 0 0 0 0 0 0 E0 0
66 66 FE E6 0
66 66 6 0 0 0 0 0 0 60 FE 0 66 18 60 86 0
66 66 78 1E 0 1E 0 E0 0 E0 0 0 0 0 0 0 E0 FE 0
66 66 E0 1E 0 6 60 80 18 66 FE 0
66 66 9E 0 1E F8 0 0 0 0 0 0 E0 E0 0 0 FE E6 0
66 66 6 80 0 0 0 0 0 0 80  18 18 60 86 0
66 66 F8 78 1E 0 1E 0 E0 0 0 0 0 0 0 0 E0 0
66 66 1E 0 6 60 80 18 0 0 0 0 66 FE 0
66 66 9E 0 1E 0 0 0 0 0 1E 0 E0 0 E0 0 0 FE E6 0
66 66 6 98 0 1E 0 6 60 80  18 18 60 86 0
66 66 78 1E 0 1E 9E 0 1E 0 0 0 0 0 0 E0 0
66 66 E0 1E 0 6 80 0 0 0 0 0 0 66 FE 0

Nascosti tra questi byte ci sono le sequenze che mi interessano es. 0 60 FE 0 oppure 0 66 FE 0.

Il secondo stato penso dovrebbe essere rilevare il passaggio delle sequenze che mi interessano e salvarle in una variabile di stato ...ma non so come fare.
Mi potete aiutare?

Grazie in anticipo
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Jun 20, 2018, 06:45 am
Mi fai una grande cortesia?
riparti da capo con lo spiegare "cosa" vuoi fare, e non "come" lo vuoi fare?
qualche idea credo di averla, ma....
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 20, 2018, 09:46 am
Certo!
La mia esigenza è di comandare due ventole PWM  ricevendo i comandi da rete LinBus.
La rete Lin Bus esiste già.
Ho un codice in grado di leggere il traffico sulla rete che mi restituisce una "sbrodolata" di byte (un esempio lo puoi vedere sopra).
Analizzando il traffico sulla rete ho identificato i gruppi di byte che corrispondono ai comandi di funzionamento per le ventole che sono:

0 60 FE 0 = ventola SX alle velocità 3
0 66 FE 0 = ventola SX alle velocità 2
0 78 FE 0 = ventola SX alle velocità 1
0 F8 0 = ventola DX alle velocità 3
0 F8 FE 0 = ventola DX alle velocità 2
0 78 0 0 0 0 F8 FE 0 = ventola DX alle velocità 1

Quello che non so fare ora è impostare due variabili di stato che cambiano ogni qualvolta passa sulla rete una delle sequenze di comando indicate sopra.
Dallo stato di queste variabili farei dipendere il comando PWM alle ventole.

Grazie per il tuo interessamento
 
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Jun 20, 2018, 10:07 am
Stasera, dopo il lavoro, vedi di mettere insieme qualcosa
Se mi dai due dritte tu sullo hardware, perché la cosa interssa anche me
Title: Re: Comandare ventola PWM con LIN BUS
Post by: gpb01 on Jun 20, 2018, 11:28 am
>PM68: ... come ti dicevo devi identificare i vari stati ... leggi da seriale, sei in stato 0, ogni volta che leggi uno ZERO te lo segni e verifichi se il successivo è ancora ZERO. Se si, rimani in tale stato, se NO, verifichi che sia 60, oppure 66, oppure 78, oppure F8 ... questo ti porta a 4 differenti stati, in ognuno di questi verifichi se il carattere successivamente ricevuto è quello giusto, es. sei nello stato in cui hai ricevuto 66, se ricevi FE è un carattere valido e passi allo stato successivo (ventola SX alle velocità 2), altrimenti NON è valido e torni allo stato ZERO.

E' lungo, ma con qualche trucchetto (es. uso di array per memorizzare le giuste sequenze), NON è difficile da realizzare.

In pratica è un "parser" che cerca determinate sequenze e lo fa in tempo reale.

Guglielmo
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Jun 20, 2018, 11:53 am
Alcune cose però non tornano
Linbus non lavora proprio così...
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Jun 20, 2018, 11:55 am
Comunque, stasera ci guardo e tento di darti due dritte
Title: Re: Comandare ventola PWM con LIN BUS
Post by: gpb01 on Jun 20, 2018, 12:01 pm
... LIN Protocol and Physical Layer Requirements (http://www.ti.com/lit/an/slla383/slla383.pdf) ... con tutte le specifiche e la spiegazione del protocollo.

Ho idea che il problema va proprio affrontato in modo diverso ... ::)

Guglielmo
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 20, 2018, 01:54 pm
Stasera, dopo il lavoro, vedi di mettere insieme qualcosa
Se mi dai due dritte tu sullo hardware, perché la cosa interssa anche me
L'hardware è semplicissimo:  Arduino DUE con LIN Transceiver MCP2004A.

Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 20, 2018, 02:02 pm
>PM68: ... come ti dicevo devi identificare i vari stati ... leggi da seriale, sei in stato 0, ogni volta che leggi uno ZERO te lo segni e verifichi se il successivo è ancora ZERO. Se si, rimani in tale stato, se NO, verifichi che sia 60, oppure 66, oppure 78, oppure F8 ... questo ti porta a 4 differenti stati, in ognuno di questi verifichi se il carattere successivamente ricevuto è quello giusto, es. sei nello stato in cui hai ricevuto 66, se ricevi FE è un carattere valido e passi allo stato successivo (ventola SX alle velocità 2), altrimenti NON è valido e torni allo stato ZERO.

E' lungo, ma con qualche trucchetto (es. uso di array per memorizzare le giuste sequenze), NON è difficile da realizzare.

In pratica è un "parser" che cerca determinate sequenze e lo fa in tempo reale.

Guglielmo
Grazie Guglielmo, ho capito come intendi gli stati. Questa sera inizio a lavorarci.
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Jun 20, 2018, 05:41 pm
mah, ho dei dubbi, e te li esprimo subito
primo) il protocollo prevede una trasmissione che inizia con 0x55 (che poi sarebbe solo una sequenza di 01 alternati) e non li vedo nei tuoi dati, questo probabilemte significa solo che il trasnceiver "strippa" quasto byte, che in effetti serve solo per dare il sincronismo e l'isocronia tra i dispositivi
secondo) il protocollo prevede che il master trasmetta UN solo byte che contiene, se ho letto bene, sia indirizzo dello slave che comando, con 2 bit di parità, e questo è ben strano da fare con arduino.
io questo lo interpreto che l'indirizzo è il primo byte nelle tue sequenze, ma dovrebbe essere uguale per i tre comandi della ventola di destra, e nel tuo flusso non è così
terzo) lo slave (o il master se il comando richiede argomenti) trasmette subito dopo da 0 a 8 byte (0 se non è prevista risposta, ovviamente) con un checksum di un byte (opzionale, per modo di dire, sembra che nulla nel protocollo sia lasciato libero, il progettista del sistema deve decidere utti i dettagli, quindi il checksum potrebbe non esserci, ma se c'è non è opzionale)
e qui, io mi aspetto che per comandi omologhi (che vuol dire simili tra due dispositivi simili) la lunghezza del messaggio sia la stessa, e nei tuoi dati non è così
quarto) se ci fai caso la sequenza "0 78 0 0 0 0 F8 FE 0 = ventola DX alle velocità 1" contiene al suo interno la sequenza "0 F8 0 = ventola DX alle velocità 3", che mi fa pensare a qualcosa di strano
comunque, il tuo problema adesso è riconoscere sequenze, e guardacaso anche il mio (in un'altro contesto) quindi sono ben lieto di condividere con te, lasciami solo il tempo di "dare forma" alle mie idee
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Jun 20, 2018, 06:25 pm
Ok, fatto al volo
NON lo ho fatto per te, ma perchè mi serviva per altro, ma comunque sarai il primo a provarlo, io non ho una DUE per provare, non posso nemeno compilare, dato che non ho le librerie
per prima cosa la loop()
Code: [Select]

void loop(void)
{
    byte comando = 0;
    if (Serial1.available())
      {
        // un byte disponibile
        // passo a trattarlo
        comando = parserizza((byte)Serial1.read());
        // tutto il lavoro lo fa la parserizza
        // che restituisce un valore numerico
        // 0 per non trovato
        // 1 per trovato primo comando
        // 2 per trovato.......
    }

    switch (comando)
    {
        case 0:
            // nessun comando da eseguire
            break;

        case 1:
            // qui eseguo il primo comando
            break;

        case 2:
            // qui eseguo il secondo comando
            break;

        // e via così....
        default:
            // comando non trovato
    }
}

come vedi ho semplicemente passato il lavoro sporco ad una funzione apposita, che riceve un byte per volta dalla loop, solo se la seriale è available
e restituisce 0 se non ha ancora trovato un comando valido
il numero del comando se lo ha trovato
e poi una switch case esegue il comando, abbastanza banale
per seconda cosa la funzione di parser
Code: [Select]

byte parserizza(byte in)
{
    // riceve byte a byte un comando e lo usa per riconoscere il comando complessivo
    // dichiaro una matrice di matrici di byte
    // il problema è che le sequenza non hanno lunghezza uguale tra loro
    // quindi devo anche dichiarare un array di lunghezze
    // potessi usare le stringhe, sarebbe comodo ma esistono degli 00 nel flusso
    // quindi una matrice bidimensionale di byte (larga quanto il più lungo comando)
    // con una matrice monodimensionale di lunghezze
    byte comandi[6][9];// 6 comandi per nove byte massimi
    byte lunghez[6]; // 6 lunghezze
    // inizializzo
    comandi[1] = {0x00, 0x60, 0xFE, 0x00};
    lunghez[1] = 4;
    // e qui si prosegue per gli altri 5 comandi possibili
    // siccome leggo il comando byte a byte devo tenere traccia di quanto lungo ho letto
    // e siccome devo confrontarlo con 6 possibili comandi devo avere sei indici, uno per possibile comando
    // statico per non perdere l'informazione da un ingresso al successivo
    static byte trovato[6] = {0, 0, 0, 0, 0, 0}; // variabili locali vanno inizializzate

    // adesso conosco un byte e vedo se corrisponde con la posizione raggiunta in ognuno dei possibili comandi
    for (byte i = 0; i < 6; i++)
    {
        // per ogni comando
        if (comandi[i][trovato[i]] != in)
        {
            // se il byte 'in' non corrisponde al byte in posizione [trovato[i]]
            // non e' il carattere giusto
            trovato[i] = 0; // riporto indietro il contatore
        }
        else
        {
            // è il carattere giusto
            // delle due l'una
            // o siamo alla fine del comando oppure no
            if (trovato[i] == lunghez[i])
            {
                // comando finito, ho trovato tutti i byte
                // riporto a zero l'indice, per ripartire bene la prossima volta
                trovato[i] = 0;
                // me ne esco da questa funzione restituendo il numero del comando trovato
                // più uno perchè zero indica comando non trovato
                return i + 1;
            }
            else
            {
                // comando non ancora finito, devo aspettare altri byte per sepere se è il giusto
                // aggiorno l'indice per controllare il prossimo byte
                trovato[i]++;
            }
        }
    }

    // se sono arrivato fin qui vuol dire che non ho trovato nessun comando
    // restituisco 0 -> comando non trovato
    return 0;
}

Tieni presente che ho appena finito di scriverla, e non so se compila, casomai vedi che problemi ti da
fondamentalmnte una matrice bidimensionale di byte, che contengono le sequenze possibili di byte in ricezione
letta "riga a riga" si può interpretare come una matrice di sequenze
quindi, in una for, sequenza per sequenza, controlla se il byte appena arrivato corrisponde al punto che ha già raggiunto, se corrisponde e ha finito la sequenza restiruisce il numero della sequenza riconosciuta
se corrisponde e non ha finito la sequenza "avanza di uno" nella lettura della sequenza
se non corrisponde riporta a zero l'indice di lettura
se non corrisponde per nessuna sequenza restituisce 0 per dire che non ha ancora trovato nulla
Personalmente credo che non andrà, per i dubbi che ti avevo esposto prima, ma tentar onn nuoce
a comunque NON accenderà mai la ventola DX a velocità 1, dato che con quella sequenza comunque interpreta ventola DX velocità 3
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 20, 2018, 09:45 pm
Grazie Standardoil!
Io sono un principiante di Arduino e non ho basi di informatica. Ho letto il tuo codice e qualcosa ho capito ma ora mi concentro e lo studio bene.
Ti faccio sapere appena lo provo.

Concordo con te sui dubbi che mi hai espresso riguardo la "sbrodolata" di byte che non rispetta il protocollo LinBus. Ho cercato una tabulazione che desse una logica uguale a tutti i frame ma non l'ho trovata.
Può esserci qualcosa che sbaglio nella lettura?
All'inizio avevo sbagliato la velocità, avevo messo 9600 mentre la LinBus trasmette a 19200 e leggevo altri dati e molti codici 7F che è il codice di errore.
Ho provato anche a variare la uint8_t rxByte[8] e l'ho portata a 16 e 32 ma non è cambiato niente.
Se hai qualche suggerimento posso modificare e provare.

Io ho supposto fosse una LinBus perchè ho visto sulla scheda elettronica che comanda queste ventole che c'è un integrato TJA1020 che è un LIN transceiver. Però la macchina è Giapponese, forse loro hanno protocolli diversi. Inoltre la Toyota non è tra i costruttori che hanno promosso lo sviluppo del protocollo LinBus.
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Jun 20, 2018, 10:02 pm
Purtroppo qui non posso aiutarti, non conosco il protocollo LIN, tutto quello che so lo ho letto oggi nei documenti postati da Guglielmo, e lo ho scritto qui...
attento che ho fatto una piccola modifica al mio post precedente, avevo dichiarato la variabile comando in un blocco 'if', andava dichiarata subito prima, ho spostato la riga
continuo a non poter compilare, quindi non posso garantire nulla, ma a occhio sembra poter andare
in effetti somiglia molto ad una macchina a stati, in realtà ad un array di 6 macchine a stati, che aggiorna 6 stati per ogni byte ricevuto
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 20, 2018, 11:02 pm
Ma "parserizza" necessita di una libreria? Mi dice 'parserizza' was not declared in this scope.
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Jun 20, 2018, 11:13 pm
no' è tutto buon 'C' in sorgente
dubbio: oltra alla loop() hai copiato anche la parserizza(), vero?
anno' forse ho capito
se bob compila la parserizza ti da una vagonata di errori
vedo se ci ho lasciato dentro qualche castroneria.......
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Jun 20, 2018, 11:18 pm
ho sbagliato a inizializzare gli array
così adesso a me compila, ma natiralmente mi manca tutto il resto
Code: [Select]

// di Nelson "StandardOil"
// Idea da sviluppare:
void setup(void)
{
}

void loop(void)
{ byte comando = 0;
    if (Serial1.available())
       

    {
        // un byte disponibile
        // passo a trattarlo
        comando = parserizza((byte)Serial1.read());
        // tutto il lavoro lo fa la parserizza
        // che restituisce un valore numerico
        // 0 per non trovato
        // 1 per trovato primo comando
        // 2 per trovato.......
    }

    switch (comando)
    {
        case 0:
            // nessun comando da eseguire
            break;

        case 1:
            // qui eseguo il primo comando
            break;

        case 2:
            // qui eseguo il secondo comando
            break;

        // e via così....
        default:
            // comando non trovato
            break;
    }
}

byte parserizza(byte in)
{
    // riceve byte a byte un comando e lo usa per riconoscere il comando complessivo
    // dichiaro una matrice di matrici di byte
    // il problema è che le sequenza non hanno lunghezza uguale tra loro
    // quindi devo anche dichiarare un array di lunghezze
    // potessi usare le stringhe, sarebbe comodo ma esistono degli 00 nel flusso
    // quindi una matrice bidimensionale di byte (larga quanto il più lungo comando)
    // con una matrice monodimensionale di lunghezze
    byte comandi[6][9];// 6 comandi per nove byte massimi
    byte lunghez[6]; // 6 lunghezze
    // inizializzo
    comandi[1][1] = 0x00;
    comandi[1][2] = 0x60;
    comandi[1][3] = 0xFE;
    comandi[1][4] = 0x00;
    lunghez[1] = 4;
    // e qui si prosegue per gli altri 5 comandi possibili
    //siccome leggo il comando byte a byte devo tenere traccia di quanto lungo ho letto
    //e siccome devo confrontarlo con 6 possibili comandi devo avere sei indici, uno per possibile comando
    // statico per non perdere l'informazione da un ingresso al successivo
    static byte trovato[6] = {0, 0, 0, 0, 0, 0}; // variabili locali vanno inizializzate

    // adesso conosco un byte e vedo se corrisponde con la posizione raggiunta in ognuno dei possibili comandi
    for (byte i = 0; i < 6; i++)
    {
        // per ogni comando
        if (comandi[i][trovato[i]] != in)
        {
            // se il byte 'in' non corrisponde al byte in posizione [trovato[i]]
            // non e' il carattere giusto
            trovato[i] = 0; // riporto indietro il contatore
        }
        else
        {
            // è il carattere giusto
            // delle due l'una
            // o siamo alla fine del comando oppure no
            if (trovato[i] == lunghez[i])
            {
                // comando finito, ho trovato tutti i byte
                // riporto a zero l'indice, per ripartire bene la prossima volta
                trovato[i] = 0;
                // me ne esco da questa funzione restituendo il numero del comando trovato
                // più uno perchè zero indica comando non trovato
                return i + 1;
            }
            else
            {
                // comando non ancora finito, devo aspettare altri byte per sepere se è il giusto
                // aggiorno l'indice per controllare il prossimo byte
                trovato[i]++;
            }
        }
    }

    // se sono arrivato fin qui vuol dire che non ho trovato nessun comando
    // restituisco 0 -> comando non trovato
    return 0;
}

consiglio: sposta l'inizializzazione degli array prima della setup
così diventano globali e non vengono ripetuti tutte le volte
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 21, 2018, 10:31 am
dubbio: oltra alla loop() hai copiato anche la parserizza(), vero?


ma dove trovo la parserizza()?
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Patrick_M on Jun 21, 2018, 03:33 pm
nel codice del post #29 ;)
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 21, 2018, 10:00 pm
Ho completato il codice scritto da Nelson "StandardOil" con tutti i miei parametri.
La compilazione non da errori.
L'ho provato ma non si accende niente, sicuramente ho sbagliato qualcosa.
Metto il codice di seguito:

Code: [Select]

// CODICE RILEVAZIONE EVENTI SU LINBUS LEXUS e COMANDO VENTOLE PWM
// di Nelson "StandardOil"
// Idea da sviluppare:

#include <DuePWM.h>
#define PIN_RXE 19
#define PIN_TXE 18
#define PIN_CS 2
#define PIN_FAULT 9
#define PWM_FREQ1  20000
#define PWM_FREQ2  20000
uint8_t rxByte[8];
uint32_t pwm_duty = 0;
DuePWM pwm( PWM_FREQ1, PWM_FREQ2 );

void setup(void)
{
  pinMode(PIN_TXE, OUTPUT);
  pinMode(PIN_CS, OUTPUT);
  digitalWrite(PIN_TXE, HIGH);
  digitalWrite(PIN_CS, HIGH);
  Serial.begin(9600); //debug serial
  Serial.println("Due debug Comms");
  Serial1.begin(19200, SERIAL_8E1); //LIN Serial Rx, 8E1 is BMW iBus standard
  pwm.setFreq1( PWM_FREQ1 );
  pwm.setFreq2( PWM_FREQ2 );
  pwm.pinFreq1( 6 );  // Pin 6 freq set to "pwm_freq1" on clock A
  pwm.pinFreq2( 7 );  // Pin 7 freq set to "pwm_freq2" on clock B
}

void loop(void)
{ byte comando = 0;
  if (Serial1.available())

  {
    // un byte disponibile
    // passo a trattarlo
    comando = parserizza((byte)Serial1.read());
    // tutto il lavoro lo fa la parserizza
    // che restituisce un valore numerico
    // 0 per non trovato
    // 1 per trovato primo comando
    // 2 per trovato.......
  }

  switch (comando)
  {
    case 0:
      // nessun comando da eseguire
      break;

    case 1:
      pwm_duty = 60; // 75% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
      break;

    case 2:
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 50% duty cycle on Pin 6
      break;

    case 3:
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 25% duty cycle on Pin 6
      break;

    case 4:
      pwm_duty = 60; // 75% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 75% duty cycle on Pin 6
      break;

    case 5:
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 50% duty cycle on Pin 6
      break;

    default:
      // comando non trovato
      break;
  }
}

byte parserizza(byte in)
{
  // riceve byte a byte un comando e lo usa per riconoscere il comando complessivo
  // dichiaro una matrice di matrici di byte
  // il problema è che le sequenza non hanno lunghezza uguale tra loro
  // quindi devo anche dichiarare un array di lunghezze
  // potessi usare le stringhe, sarebbe comodo ma esistono degli 00 nel flusso
  // quindi una matrice bidimensionale di byte (larga quanto il più lungo comando)
  // con una matrice monodimensionale di lunghezze
  byte comandi[6][9];// 6 comandi per nove byte massimi
  byte lunghez[6]; // 6 lunghezze
  // inizializzo
  comandi[1][1] = 0x00;
  comandi[1][2] = 0x60;
  comandi[1][3] = 0xFE;
  comandi[1][4] = 0x00;
  lunghez[1] = 4;

  comandi[2][1] = 0x00;
  comandi[2][2] = 0x66;
  comandi[2][3] = 0xFE;
  comandi[2][4] = 0x00;
  lunghez[2] = 4;

  comandi[3][1] = 0x00;
  comandi[3][2] = 0x78;
  comandi[3][3] = 0xFE;
  comandi[3][4] = 0x00;
  lunghez[3] = 4;

  comandi[4][1] = 0x00;
  comandi[4][2] = 0xF8;
  comandi[4][3] = 0x00;
  lunghez[4] = 3;

  comandi[5][1] = 0x00;
  comandi[5][2] = 0xF8;
  comandi[5][3] = 0xFE;
  comandi[5][4] = 0x00;
  lunghez[5] = 4;

  //siccome leggo il comando byte a byte devo tenere traccia di quanto lungo ho letto
  //e siccome devo confrontarlo con 6 possibili comandi devo avere sei indici, uno per possibile comando
  // statico per non perdere l'informazione da un ingresso al successivo
  static byte trovato[6] = {0, 0, 0, 0, 0, 0}; // variabili locali vanno inizializzate
  // adesso conosco un byte e vedo se corrisponde con la posizione raggiunta in ognuno dei possibili comandi
  for (byte i = 0; i < 6; i++)

  {
    // per ogni comando
    if (comandi[i][trovato[i]] != in)
    {
      // se il byte 'in' non corrisponde al byte in posizione [trovato[i]]
      // non e' il carattere giusto
      trovato[i] = 0; // riporto indietro il contatore
    }
    else
    {
      // è il carattere giusto
      // delle due l'una
      // o siamo alla fine del comando oppure no
      if (trovato[i] == lunghez[i])
      {
        // comando finito, ho trovato tutti i byte
        // riporto a zero l'indice, per ripartire bene la prossima volta
        trovato[i] = 0;
        // me ne esco da questa funzione restituendo il numero del comando trovato
        // più uno perchè zero indica comando non trovato
        return i + 1;
      }
      else
      {
        // comando non ancora finito, devo aspettare altri byte per sepere se è il giusto
        // aggiorno l'indice per controllare il prossimo byte
        trovato[i]++;
      }
    }
  }

  // se sono arrivato fin qui vuol dire che non ho trovato nessun comando
  // restituisco 0 -> comando non trovato
  return 0;
}


Vorrei visualizzare sulla seriale qualche variabile per capire cosa sta facendo e magari mi aiuta a capire dove si blocca. Pensavo alla variabile "trovato"  però se aggiungo
Code: [Select]
      Serial.println(trovato[i], HEX);   
mi dice 'i' was not declared in this scope.
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Jun 22, 2018, 12:22 am
infatti, ne trovato ne i sono globali, puoi farlo solo nella parserizza, quella variabili "vivono" solo nella parserizza()
anzi, per l'esattezza la i anche solo nella for() della parserizza
magari nella else, dopo la riga
Code: [Select]
// è il carattere giusto
puoi mettere una stampa, li le due variabili "vivono"
per altro non mi sembra di vedere errori, ma è anche mezzanotte passata
sono accettati consigli da forumisti più bravi di me
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 22, 2018, 08:15 pm
Funziona! E' da perfezionare ma funziona!

1° problema quando accendo il quadro la ventola parte a cannone anche se non ho comandato nessuna accensione.

Quando comando l'accensione rallenta e va correttamente alla velocità 3, quando comando di passare alla velocità 2 passa correttamente alla 2.

2° problema quando comando di passare alla velocità 1 va avanti alla 2. Probabilmente non riconosce il codice.

3° problema quando spengo non si spegne perchè non c'è niente che gli dice di spegnersi.

Dovrei mettere un millis che dopo 1 sec che non riceve comandi si spegne.
Oppure provo a vedere se c'è un codice che gira solo quando le ventole sono comandate spente.

Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 27, 2018, 01:59 pm
Un aggiornamento:

ho capito che non stavo leggendo interamente i frame sulla Lin Bus.
Dopo vari tentativi a varie velocità penso di essere arrivato alla quadra.

Serial1 19200
Serial 57600 (molto più veloce per non perdere pezzi).

Ora leggo dei frame molto regolari. Es.:

66 66 78 1E 0 1E 0 E0 0 E0 0 0 FE E6 0
66 66 6 0 0 0 0 0 0 0 FE FE 0
66 66 9E 0 1E 0 0 0 0 0 0 E0 0
66 66 1E 0 6 60 80
18 18 60 86 0 

66 66 78 1E 0 1E 0 E0 0 E0 0 0 FE E6 0
66 66 6 0 0 0 0 0 0 0 FE FE 0
66 66 9E 0 1E 0 0 0 0 0 0 E0 0
66 66 1E 0 6 60 80
18 18 60 86 0 

66 66 78 1E 0 1E 0 E0 0 E0 0 0 FE E6 0
66 66 6 0 0 0 0 0 0 0 FE FE 0
66 66 9E 0 1E 0 0 0 0 0 0 E0 0
66 66 1E 0 6 60 80
18 18 60 86 0 

66 66 78 1E 0 1E 0 E0 0 E0 0 0 FE E6 0
66 66 6 0 0 0 0 0 0 0 FE FE 0
66 66 9E 0 1E 0 0 0 0 0 0 E0 0
66 66 1E 0 6 60 80
18 18 60 86 0 

Ho analizzato 45 sec di trasmissione (circa 3400 righe) dove ho cambiato stato ogni 5 sec tenendo traccia della modifica e ho identificato i frame che girano in ogni stato.

Se qualcuno è interessato posso mandare file di Excel dove ho usato vari colori in modo che si capisce abbastanza bene come cambiano i codici.
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jun 30, 2018, 03:28 pm
Help!
Il codice non da errori ma la parserizza restituisce sempre "0".
Cosa sbaglio?
Code: [Select]

// CODICE RILEVAZIONE EVENTI SU LINBUS LEXUS e COMANDO VENTOLE PWM
// di Nelson "StandardOil":

#include <DuePWM.h>
#define PIN_RXE 19
#define PIN_TXE 18
#define PIN_CS 2
#define PIN_FAULT 9
#define PWM_FREQ1  20000
#define PWM_FREQ2  20000
uint16_t rxByte[16];
uint32_t pwm_duty = 0;
DuePWM pwm( PWM_FREQ1, PWM_FREQ2 );

void setup(void)
{
  pinMode(PIN_TXE, OUTPUT);
  pinMode(PIN_CS, OUTPUT);
  digitalWrite(PIN_TXE, HIGH);
  digitalWrite(PIN_CS, HIGH);
  Serial.begin(57600); //debug serial
  Serial.println("Due debug Comms");
  Serial1.begin(19200, SERIAL_8E1); //LIN Serial Rx, 8E1 is BMW iBus standard
  pwm.setFreq1( PWM_FREQ1 );
  pwm.setFreq2( PWM_FREQ2 );
  pwm.pinFreq1( 6 );  // Pin 6 Vent SX freq set to "pwm_freq1" on clock A
  pwm.pinFreq2( 7 );  // Pin 7 Vent DX freq set to "pwm_freq2" on clock B
}

void loop(void)
{ byte comando = 0;
  if (Serial1.available())
  {
    // un byte disponibile -  passo a trattarlo
    comando = parserizza((byte)Serial1.read());
    // tutto il lavoro lo fa la parserizza che restituisce un valore numerico
    // 0 per non trovato
    // 1 per trovato primo comando
    // 2 per trovato.......
  }

  switch (comando)
  {
    case 0: //comando non trovato non fa niente

      break;

    case 1: //vent SX 3
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
      break;

    case 2: //vent SX 3
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
      break;

    case 3: //vent SX 3
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
      break;

//HO DOVUTO CANCELLARE UN PEZZO PER NON ECCEDERE I 9000 CARATTERI

    case 47: //SPENTO_VENT_SX
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 0% duty cycle on Pin 6*/
      break;

    default:

      break;
  }
}

byte parserizza(byte in)
{
  // riceve byte a byte un comando e lo usa per riconoscere il comando complessivo
  // dichiaro una matrice di matrici di byte
  // il problema è che le sequenza non hanno lunghezza uguale tra loro
  // quindi devo anche dichiarare un array di lunghezze
  // potessi usare le stringhe, sarebbe comodo ma esistono degli 00 nel flusso
  // quindi una matrice bidimensionale di byte (larga quanto il più lungo comando)
  // con una matrice monodimensionale di lunghezze
  byte comandi[47][57];// 47 comandi per 57 byte massimi
  byte lunghez[5]; // 5 lunghezze
  // inizializzo
  //SX3
  comandi [1][1] = 0x66;
  comandi [1][2] = 0x66;
  comandi [1][3] = 0x78;
  comandi [1][4] = 0x1E;
  comandi [1][5] = 0x00;
  comandi [1][6] = 0x1E;
  comandi [1][7] = 0x00;
  comandi [1][8] = 0xE0;
  comandi [1][9] = 0x00;
  comandi [1][10] = 0xE0;
  comandi [1][11] = 0x00;
  comandi [1][12] = 0x00;
  comandi [1][13] = 0xFE;
  comandi [1][14] = 0xE6;
  comandi [1][15] = 0x00;
  comandi [1][16] = 0x66;
  comandi [1][17] = 0x66;
  comandi [1][18] = 0x06;
  comandi [1][19] = 0x00;
  comandi [1][20] = 0x00;
  comandi [1][21] = 0x00;
  comandi [1][22] = 0x00;
  comandi [1][23] = 0x00;
  comandi [1][24] = 0x00;
  comandi [1][25] = 0x00;
  comandi [1][26] = 0xFE;
  comandi [1][27] = 0xFE;
  comandi [1][28] = 0x00;
  comandi [1][29] = 0x66;
  comandi [1][30] = 0x66;
  comandi [1][31] = 0x9E;
  comandi [1][32] = 0x00;
  comandi [1][33] = 0x1E;
  comandi [1][34] = 0xF8;
  comandi [1][35] = 0x00;
  comandi [1][36] = 0x00;
  comandi [1][37] = 0x00;
  comandi [1][38] = 0x00;
  comandi [1][39] = 0x00;
  comandi [1][40] = 0x00;
  comandi [1][41] = 0xE0;
  comandi [1][42] = 0xFE;
  comandi [1][43] = 0x00;
  comandi [1][44] = 0x66;
  comandi [1][45] = 0x66;
  comandi [1][46] = 0x1E;
  comandi [1][47] = 0x00;
  comandi [1][48] = 0x06;
  comandi [1][49] = 0x60;
  comandi [1][50] = 0x80;
  comandi [1][51] = 0x18;
  comandi [1][52] = 0x18;
  comandi [1][53] = 0x60;
  comandi [1][54] = 0x86;
  comandi [1][55] = 0x00;
  lunghez [1] = 55;
  //SX3
  comandi [2][1] = 0x66;
  comandi [2][2] = 0x66;
  comandi [2][3] = 0x78;
  comandi [2][4] = 0x1E;
  comandi [2][5] = 0x00;
  comandi [2][6] = 0x1E;
  comandi [2][7] = 0x00;
  comandi [2][8] = 0xE0;
  comandi [2][9] = 0x00;
  comandi [2][10] = 0xE0;
  comandi [2][11] = 0x00;
  comandi [2][12] = 0x00;
  comandi [2][13] = 0xFE;
  comandi [2][14] = 0xE6;
  comandi [2][15] = 0x00;
  comandi [2][16] = 0x66;
  comandi [2][17] = 0x66;
  comandi [2][18] = 0x06;
  comandi [2][19] = 0x9E;
  comandi [2][20] = 0x00;
  comandi [2][21] = 0x00;
  comandi [2][22] = 0x00;
  comandi [2][23] = 0x00;
  comandi [2][24] = 0x00;
  comandi [2][25] = 0x00;
  comandi [2][26] = 0x60;
  comandi [2][27] = 0xFE;
  comandi [2][28] = 0x00;
  comandi [2][29] = 0x66;
  comandi [2][30] = 0x66;
  comandi [2][31] = 0x9E;
  comandi [2][32] = 0x00;
  comandi [2][33] = 0x1E;
  comandi [2][34] = 0xF8;
  comandi [2][35] = 0x00;
  comandi [2][36] = 0x00;
  comandi [2][37] = 0x00;
  comandi [2][38] = 0x00;
  comandi [2][39] = 0x00;
  comandi [2][40] = 0x00;
  comandi [2][41] = 0xE0;
  comandi [2][42] = 0xFE;
  comandi [2][43] = 0x00;
  comandi [2][44] = 0x66;
  comandi [2][45] = 0x66;
  comandi [2][46] = 0x1E;
  comandi [2][47] = 0x00;
  comandi [2][48] = 0x06;
  comandi [2][49] = 0x60;
  comandi [2][50] = 0x80;
  comandi [2][51] = 0x18;
  comandi [2][52] = 0x18;
  comandi [2][53] = 0x60;
  comandi [2][54] = 0x86;
  comandi [2][55] = 0x00;
  lunghez [2] = 55;

//HO DOVUTO CANCELLARE UN PEZZO PER NON ECCEDERE I 9000 CARATTERI

  //SPENTO_SX
  comandi [47][1] = 0x66;
  comandi [47][2] = 0x66;
  comandi [47][3] = 0x78;
  comandi [47][4] = 0x1E;
  comandi [47][5] = 0x00;
  comandi [47][6] = 0x1E;
  comandi [47][7] = 0x00;
  comandi [47][8] = 0xE0;
  comandi [47][9] = 0x00;
  comandi [47][10] = 0xE0;
  comandi [47][11] = 0x00;
  comandi [47][12] = 0x00;
  comandi [47][13] = 0xFE;
  comandi [47][14] = 0xE6;
  comandi [47][15] = 0x00;
  comandi [47][16] = 0x66;
  comandi [47][17] = 0x66;
  comandi [47][18] = 0x06;
  comandi [47][19] = 0x00;
  comandi [47][20] = 0x78;
  comandi [47][21] = 0x00;
  comandi [47][22] = 0x00;
  comandi [47][23] = 0x00;
  comandi [47][24] = 0x00;
  comandi [47][25] = 0x00;
  comandi [47][26] = 0xFE;
  comandi [47][27] = 0x00;
  comandi [47][28] = 0x00;
  comandi [47][29] = 0x66;
  comandi [47][30] = 0x66;
  comandi [47][31] = 0x9E;
  comandi [47][32] = 0x00;
  comandi [47][33] = 0x1E;
  comandi [47][34] = 0x00;
  comandi [47][35] = 0x00;
  comandi [47][36] = 0x00;
  comandi [47][37] = 0x00;
  comandi [47][38] = 0x00;
  comandi [47][39] = 0x00;
  comandi [47][40] = 0xE0;
  comandi [47][41] = 0x00;
  comandi [47][42] = 0x00;
  comandi [47][43] = 0x66;
  comandi [47][44] = 0x66;
  comandi [47][45] = 0x1E;
  comandi [47][46] = 0x00;
  comandi [47][47] = 0x06;
  comandi [47][48] = 0x60;
  comandi [47][49] = 0x80;
  comandi [47][50] = 0x00;
  comandi [47][51] = 0x18;
  comandi [47][52] = 0x18;
  comandi [47][53] = 0x60;
  comandi [47][54] = 0x86;
  comandi [47][55] = 0x00;
  lunghez [47] = 55;

  //siccome leggo il comando byte a byte devo tenere traccia di quanto lungo ho letto
  //e siccome devo confrontarlo con 6 possibili comandi devo avere sei indici, uno per possibile comando
  // statico per non perdere l'informazione da un ingresso al successivo
  static byte trovato[57] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // variabili locali vanno inizializzate
  // adesso conosco un byte e vedo se corrisponde con la posizione raggiunta in ognuno dei possibili comandi
  for (byte i = 0; i < 57; i++)

  {
    // per ogni comando
    if (comandi[i][trovato[i]] != in)
    {
      // se il byte 'in' non corrisponde al byte in posizione [trovato[i]]
      // non e' il carattere giusto
      trovato[i] = 0; // riporto indietro il contatore
    }
    else
    {
      // è il carattere giusto delle due l'una o siamo alla fine del comando oppure no
      Serial.println(trovato[1], HEX);
      if (trovato[i] == lunghez[i])
      {
        // comando finito, ho trovato tutti i byte riporto a zero l'indice, per ripartire bene la prossima volta
        trovato[i] = 0;
        // me ne esco da questa funzione restituendo il numero del comando trovato più uno perchè zero indica comando non trovato
        return i + 1;
      }
      else
      {
        // comando non ancora finito, devo aspettare altri byte per sepere se è il giusto
        // aggiorno l'indice per controllare il prossimo byte
        trovato[i]++;
      }
    }
  }

  // se sono arrivato fin qui vuol dire che non ho trovato nessun comando
  // restituisco 0 -> comando non trovato
  return 0;
}
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jul 30, 2018, 09:34 am
Buongiorno a tutti,
mi succede che quando la scheda Arduino Due è collegata al PC e quindi alimentata da quest'ultimo il programma si comporta in un certo modo mentre quando stacco il PC e alimento l'Arduino tramite i 12v dell'auto si comporta diversamente.
Qualcuno mi sa dare una spiegazione?
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Patrick_M on Jul 30, 2018, 12:48 pm
un sacco di disturbi direi...
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jul 30, 2018, 01:33 pm
Non pensavo ai disturbi perchè le prove le faccio a motore spento e i 12v dell'auto sono da batteria quindi stabili.
Pensavo più alla resistenza di pullup che ho messo sul segnale di ingresso perchè Arduino Due ha il processore a 3.3v. Può essere che cambiando l'alimentazione dai 5v dell'USB ai 12v dell'auto devo modificare la resistenza?
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Jul 30, 2018, 02:48 pm
Se metti lo schema sappiamo di cosa stiamo parlando
Comunque il programma che hai postato è fallato, come programma
E stai andando nella direzione sbagliata, come concetto
Adesso sono sul lavoro, stasera ti spiego...
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jul 30, 2018, 05:28 pm
Grazie Nelson,
aspetto le tue spiegazioni.
Di seguito lo schema:

Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Jul 30, 2018, 08:24 pm
Dopo  una giornata in ditta col condizionatore guasto e due ore dal medico in 30 in sala d'attesa mi sono preso il colpo della strega con l'aria condizionata a casa; se sarò quindi un po' brusco mi sopporterai.....
la prima cosa che ho notato nel tuo programma attuale è che hai dimensionato 47 comandi ma l'array di lunghezze è lungo solo 5; dovrebbe, anzi "deve" avere la stessa lunghezza della prima dimensione dell'array dei comandi, messo così come lo hai messo tu il programma se va lo fa solo per fortuna
per seconda cosa, 47 comandi per solo 2 ventole a tre velocità (5 contando "fermo" e "massimo") sono troppi, non è la strada giusta
Allora ho cercato il datasheet del chip mcp2004: è poco più di un puro convertitore di livello, dal 12 V del LIN bus alla tensione di lavoro dell'arduino, non interpreta i dati, ne fa sincronizzazione o simili, tutto lavoro che quindi deve fare l'arduino, e li tu non lo fai
In particolare non "strippa" il codice 0x55 che sarebbe l'inizio della trasmissione, e in nessuno dei tuoi "elenchi di cose ricevute" si vede. Se non lo vedi è perchè non lo ricevi, e se non lo ricevi è perchè hai problemi a livello di comunicazione lato LIN bus
e qui ho visto un paio di cose: di default il LIN bus sembra andare a 9600bps, non 19200, ti conviene provare un po' di velocità, con costanza apri la seriale a 19200, poi a 9600, poi a 4800, e via così
poi la parità che usi (8E1) non è lo standard LIN, viene usata da BMW, ma non in un LIN bus, in una sua cosa propietaria
da una ricerca è saltato fuori che varie persone sono riuscite a leggere il LINbus con una UNO e la sua software serial, quindi nemmeno c'è la possibilità di cambiare parità, ergo usa la parità di default
inoltre io sono sempre convinto che la trasmissione LIN è composta da massimo 11 byte preceduti da un "silenzio" lungo almeno 13 bit
1 byte 0x55 Start e sincronismo tra i device
1 byte di indirizzo, dove alcuni bit specificano l'indirizzo, e altri sono di parità aggiuntiva
1, 2, 4 oppure 8 (ma non 3 o 5 o 6 o 7) byte di "risposta" (viene chiamata risposta anche quando viene trasmessa dal master)
1 byte di CRC o checksum o quello che è
ora, 1 + 2 + al massimo 8 fa al massimo 11
dagli esempi che ho trovato sono sicuro che la lunghezza di messaggi "omologhi" (che vuol dire che fanno cose simili) è costante, dipende dal tipo di messaggio, ma non esiste che per regolare una ventola un messaggio sia lungo 7 mentre per regolare l'altra il messaggio sia lungo 45, anche perchè è evidente che le ventole sono "simili" come progetto, quindi non è che in sede di installazione l'operaio che le monta debba scoprire la lunghezza del messaggio
da ultimo tieni presente che il protocollo LINbus prevede delle tolleranze sulle velocità, e siccome i device slave "non" hanno un oscillatore a cristallo, ma si regolano in base alla cadenza dello 0x55 iniziale non è escluso che le tolleranze dell'oscillatore di arduino non vadano bene , potrebbe essere necessario, per migliorare la qualità della trasmissione, di "aggiustare" di qualche percento i bps della seriale
Comunque, ripeto, fino a che non vedi gli 0x55 NON stai ricevendo correttamente dal lato LINbus
da ultimo lo schema: spero tu ti sia sbagliato e non sia quello lo schema che usi, dato che ti sei dimenticato di mettere il regolatore di tensione citato nella documentazione del trasnceiver
quindi vedi di mettere un regolatore a 3v3 e usare quello per connetttere la resistenza di Pull-up
Inoltre il piedino di fault lo metti in una define, ma non ne fai la pinmode e non lo usi, credo debba essere alto
E adesso lasiamelo dire: metà di queste cose te le avevo già dette, l'altra meta viene da una veloce scorsa al datasheet del 2004, che potevi fare anche tu
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Jul 30, 2018, 09:57 pm
Grazie Nelson, porta pazienza ma sono un perito meccanico.
Ora cerco di capire quello che hai scritto e metterlo in pratica.

Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Jul 30, 2018, 10:03 pm
Tranquillo, io son perito elettrotecnico
basta non essere ingannieri................
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Aug 04, 2018, 10:56 pm
Buona sera,
ho corretto gli errori che avevo fatto nel circuito, così mi sembra vada bene, lo potete vedere nell'allegato.
Ho provato a leggere la LIN con il codice sotto ma legge per 2-3 sec poi non riceve più niente. Nei pochi secondi che legge qualche 0x55 c'è.

Code: [Select]


#define PIN_TXE 18
#define PIN_CS 2
#define PIN_FAULT 9
uint8_t rxByte[8];

void setup() {
  pinMode(PIN_TXE, OUTPUT);
  pinMode(PIN_CS, OUTPUT);
  pinMode(PIN_FAULT, OUTPUT);
  digitalWrite(PIN_TXE, LOW);
  digitalWrite(PIN_CS, HIGH);
  digitalWrite(PIN_FAULT, HIGH);
  Serial1.begin(9600);
  Serial.begin(19200);
  Serial.println("Due debug Comms");

  delay(100);
}

void loop() {
  byte actuallyRead = Serial1.readBytes(rxByte, 16);
  if (actuallyRead > 0)
  {
    for (uint32_t i = 0; i < actuallyRead; i++)
    {
      Serial.println(rxByte[i], HEX);
    }
  }
}
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Aug 05, 2018, 10:14 pm
Per prima cosa io non ti ho indicato come modificare il circuito, ti ho detto che non era quello appropriato, non associarmi con azioni che non condivido...
Poi, non capisco perché dopo aver modificato il circuito hai anche sentito l'esigenza di scrivere un programma nuovo e sbagliato
Adesso sono in ferie, e poco posso fare
Ma se analizzi per bene il tuo programma un qualche problema lo trovi
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Aug 06, 2018, 10:48 am
Scusa Nelson, ho corretto la frase.
Ma c'è ancora qualcosa di sbagliato nel circuito?

Il programma non l'ho scritto adesso, è sempre lo stesso che uso per leggere i messaggi che girano sulla LIN.
Con questo programma leggo le stringhe, faccio l'analisi per capire quali sono i comandi che poi riporto nell'alto programma che comanda le ventole.

E' qui l'errore:"uint8_t rxByte[8];"?
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Aug 08, 2018, 10:56 am
Ciao a tutti,
ho sistemato la schedina che aveva una saldatura difettosa, ho eliminato alcune cose che sul datasheet del MCP2004 davano come opzionali, in allegato lo schema.
Ho corretto l'errore nel codice (spero) e messo la parità std .
Il pin Fault l'ho messo LOW per disabilitare la TX che non mi serve (da datasheet MCP2004).
Ora riesco a leggere la LIN con continuità.
Ho fatto varie prove a 4800, 9600, 19200 ma il byte 0x55 c'è solo a 9600 quindi considero 9600 la velocità corretta.
Le stringhe che leggo con tutto spento sono così:

55 B1 0 40 0 0 38 38 0 84 CA 0
55 39 40 0 40 0 10 10 0 0 5F 0
55 78 0 0 80 0 0 0 0 0 7F 0
55 B4 0 3 0 0 0 0 0 0 FC 0

0x55 da il sincronismo tra i device
0xB1, 0x39, 0x78, 0xB4 sono gli indirizzi
poi ci sono 8 byte di dati
0xCA, 0X5F, 0X7F, 0xFC sarà il CRC o checksum o quello che è
0x0 chiude la stringa

Dopo una prima fase (circa 20sec) dove le stringhe sono perfettamente regolari inizia a perdere pezzi e alterna righe di 12 byte con righe da 11 e 10 e alcune stringhe diventano invece molto lunghe.
Quando si perde qualche pezzo perde anche il byte di checksum

Suggerimenti?

Grazie
Mauro

Code: [Select]

/Arduino Due Board, Programming Port, LIN Test
//Attempt to interface with MCP2004-e/p LIN Transceiver
//Due project, Receive

#define PIN_CS 2
#define PIN_FAULT 9
uint8_t rxByte[11];

void setup() {
  pinMode(PIN_CS, OUTPUT);
  pinMode(PIN_FAULT, OUTPUT);
  digitalWrite(PIN_CS, HIGH);
  digitalWrite(PIN_FAULT, LOW);
  Serial2.begin(9600);
  Serial.begin(19200);
  Serial.println("Due debug Comms");

  delay(100);
}

void loop() {
  byte actuallyRead = Serial2.readBytes(rxByte, 11); //Read UP TO 11 bytes
  if (actuallyRead > 0)
  {
    for (uint8_t i = 0; i < actuallyRead; i++)
    {
      Serial.println(rxByte[i], HEX);
    }
  }
}

Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Aug 08, 2018, 11:01 am
Tu dimensioni una rxbyte di 8 elementi, ma dopo fai una readbytes dove ne fai leggere 16, sbordando e andando a scrivere in aree di memoria dove non devi
Stesso errore che avevi fatto con lo array di lunghezze...
Consiglio: tratta la ricezione per singolo byte ricevuto
Title: Re: Comandare ventola PWM con LIN BUS
Post by: Standardoil on Aug 08, 2018, 11:20 am
E aggiungo:
Non è che non voglio metterti il programma
È che sono in ferie e ho solo tablet e furbofono
Un po' poco per scrivere programmi
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Aug 08, 2018, 11:42 am
Grazie Nelson,
i tuoi consigli mi sono utilissimi e poi mi piace dovermi sbattere un pò per trovare la soluzione.

Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Aug 12, 2018, 12:21 am
Ciao a tutti,
dopo avere sistemato il codice di lettura ho letto la LIN in modo penso corretto.
Leggo stringhe con la stessa lunghezza di 12 byte,
cominciano con 0x55,
ho 4 indirizzi ma le stringhe che interessano a me hanno indirizzo 0x78,
il 4° byte della stringa contiene l'indicazione di cosa devono fare le ventole e il riscaldamento

alcune stringhe di esempio:

55 B1 0 0 11 0 38 38 0 84 F9 0
55 39 40 0 40 0 10 10 0 0 5F 0
55 78 0 7 80 0 0 0 0 0 78 0         <---------
55 B4 0 3 0 0 0 0 0 0 FC 0

Ho modificato il codice per leggere la LIN e comandare le ventole ma non riesco a farlo funzionare.
La compilazione non da errori ma quando accendo il quadro le ventole partono al massimo e non fanno altro.
Se stampo la variabile "trovato" mi da sempre 0.
Ho fatto 1000 modifiche ma non ne esco. Ho bisogno di un esperto.
Di seguito il codice:

Code: [Select]


[code]
// CODICE RILEVAZIONE EVENTI SU LINBUS LEXUS e COMANDO VENTOLE PWM
// di Nelson "StandardOil"

#include <DuePWM.h>
#define PIN_CS 2
#define PIN_FAULT 9
#define PWM_FREQ1  20000
#define PWM_FREQ2  20000
uint32_t pwm_duty = 255; // 255 = 0% duty cycle
DuePWM pwm( PWM_FREQ1, PWM_FREQ2 );
byte comandi[16][4];// 16 comandi per 4 byte massimi
byte lunghez[1]; // 1 lunghezze

void setup(void)
{
  pinMode(PIN_CS, OUTPUT);
  pinMode(PIN_FAULT, OUTPUT);
  //digitalWrite(PIN_TXE, HIGH);
  digitalWrite(PIN_CS, HIGH);
  digitalWrite(PIN_FAULT, LOW);
  Serial2.begin(9600); //LIN Serial Rx
  Serial.begin(9600);
  pwm.setFreq1( PWM_FREQ1 );
  pwm.setFreq2( PWM_FREQ2 );
  pwm.pinFreq1( 6 );  // Pin 6 Vent SX freq set to "pwm_freq1" on clock A
  pwm.pinFreq2( 7 );  // Pin 7 Vent DX freq set to "pwm_freq2" on clock B
}
void loop(void)
{
  void Switch_Case_Comando_Ventole ();
}
byte parserizza(byte in)
{
  // riceve byte a byte un comando e lo usa per riconoscere il comando complessivo
  // dichiaro una matrice di matrici di byte
  // il problema è che le sequenza non hanno lunghezza uguale tra loro
  // quindi devo anche dichiarare un array di lunghezze
  // potessi usare le stringhe, sarebbe comodo ma esistono degli 00 nel flusso
  // quindi una matrice bidimensionale di byte (larga quanto il più lungo comando)
  // con una matrice monodimensionale di lunghezze

  // inizializzo

  //TUTTO SPENTO
  comandi[1][1] = 0x55;
  comandi[1][2] = 0x78;
  comandi[1][3] = 0x0;
  comandi[1][4] = 0x0;
  lunghez[1] = 4;

  //VENTOLA SX_3 DX_0
  comandi[2][1] = 0x55;
  comandi[2][2] = 0x78;
  comandi[2][3] = 0x0;
  comandi[2][4] = 0xB;
  lunghez[2] = 4;

  //VENTOLA SX_0 DX_3
  comandi[3][1] = 0x55;
  comandi[3][2] = 0x78;
  comandi[3][3] = 0x0;
  comandi[3][4] = 0xB0;
  lunghez[3] = 4;

  //VENTOLA SX_3 DX_3
  comandi[4][1] = 0x55;
  comandi[4][2] = 0x78;
  comandi[4][3] = 0x0;
  comandi[4][4] = 0xBB;
  lunghez[4] = 4;

  //VENTOLA SX_2 DX_3
  comandi[5][1] = 0x55;
  comandi[5][2] = 0x78;
  comandi[5][3] = 0x0;
  comandi[5][4] = 0xBA;
  lunghez[5] = 4;

  //VENTOLA SX_3 DX_2
  comandi[6][1] = 0x55;
  comandi[6][2] = 0x78;
  comandi[6][3] = 0x0;
  comandi[6][4] = 0xAB;
  lunghez[6] = 4;

  //VENTOLA SX_2 DX_0
  comandi[7][1] = 0x55;
  comandi[7][2] = 0x78;
  comandi[7][3] = 0x0;
  comandi[7][4] = 0xA;
  lunghez[7] = 4;

  //VENTOLA SX_0 DX_2
  comandi[8][1] = 0x55;
  comandi[8][2] = 0x78;
  comandi[8][3] = 0x0;
  comandi[8][4] = 0xA0;
  lunghez[8] = 4;

  //VENTOLA SX_2 DX_2
  comandi[9][1] = 0x55;
  comandi[9][2] = 0x78;
  comandi[9][3] = 0x0;
  comandi[9][4] = 0xAA;
  lunghez[9] = 4;

  //VENTOLA SX_1 DX_2
  comandi[10][1] = 0x55;
  comandi[10][2] = 0x78;
  comandi[10][3] = 0x0;
  comandi[10][4] = 0xA9;
  lunghez[10] = 4;

  //VENTOLA SX_2 DX_1
  comandi[11][1] = 0x55;
  comandi[11][2] = 0x78;
  comandi[11][3] = 0x0;
  comandi[11][4] = 0x9A;
  lunghez[11] = 4;

  //VENTOLA SX_1 DX_1
  comandi[12][1] = 0x55;
  comandi[12][2] = 0x78;
  comandi[12][3] = 0x0;
  comandi[12][4] = 0x99;
  lunghez[12] = 4;

  //VENTOLA SX_0 DX_1
  comandi[13][1] = 0x55;
  comandi[13][2] = 0x78;
  comandi[13][3] = 0x0;
  comandi[13][4] = 0x90;
  lunghez[13] = 4;

  //VENTOLA SX_1 DX_0
  comandi[14][1] = 0x55;
  comandi[14][2] = 0x78;
  comandi[14][3] = 0x0;
  comandi[14][4] = 0x9;
  lunghez[14] = 4;

  //VENTOLA SX_3 DX_1
  comandi[15][1] = 0x55;
  comandi[15][2] = 0x78;
  comandi[15][3] = 0x0;
  comandi[15][4] = 0x9B;
  lunghez[15] = 4;

  //VENTOLA SX_1 DX_3
  comandi[16][1] = 0x55;
  comandi[16][2] = 0x78;
  comandi[16][3] = 0x0;
  comandi[16][4] = 0xB9;
  lunghez[16] = 4;

  //siccome leggo il comando byte a byte devo tenere traccia di quanto lungo ho letto
  //e siccome devo confrontarlo con 4 possibili comandi devo avere 4 indici, uno per possibile comando
  // statico per non perdere l'informazione da un ingresso al successivo
  static byte trovato[4] = { 0x0, 0x0, 0x0, 0x0}; // variabili locali vanno inizializzate
  // adesso conosco un byte e vedo se corrisponde con la posizione raggiunta in ognuno dei possibili comandi
  for (byte i = 0; i < 4; i++)
  {
    // per ogni comando
    if (comandi[i][trovato[i]] != in)
    {
      // se il byte 'in' non corrisponde al byte in posizione [trovato[i]]
      // non e' il carattere giusto
      trovato[i] = 0; // riporto indietro il contatore
    }
    else
    {
      Serial.println(trovato[1], HEX);
      if (trovato[i] == lunghez[i]) // è il carattere giusto o siamo alla fine del comando oppure no
      {
        trovato[i] = 0; // ho trovato tutti i byte riporto a zero l'indice
        return i + 1; // me ne esco da questa funzione restituendo il numero del comando trovato più uno perchè zero indica comando non trovato
      }
      else
      {
        // comando non ancora finito, devo aspettare altri byte per sepere se è il giusto
        // aggiorno l'indice per controllare il prossimo byte
        trovato[i]++;
      }
    }
  }
  return 0; //restituisco 0 -> comando non trovato
}
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Aug 12, 2018, 12:27 am
Questo la seconda parte di codice:


Code: [Select]

void Switch_Case_Comando_Ventole()
{ byte comando = 0;
  if (Serial2.available())
  {
    // un byte disponibile -  passo a trattarlo
    comando = parserizza((byte)Serial2.read());
    // tutto il lavoro lo fa la parserizza che restituisce un valore numerico
    // 0 per non trovato
    // 1 per trovato primo comando
    // 2 per trovato.......
  }
  switch (comando)
  {
    case 0: //comando non trovato non fa niente

      break;

    case 1: //TUTTO SPENTO
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 0% duty cycle on Pin 6
      pwm.pinDuty( 7, pwm_duty );  // 0% duty cycle on Pin 7
      break;

    case 2:  //VENTOLA SX_3 DX_0
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 0% duty cycle on Pin 7
      break;

    case 3:  //VENTOLA SX_0 DX_3
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 0% duty cycle on Pin 6
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 75% duty cycle on Pin 7
      break;

    case 4: //VENTOLA SX_3 DX_3
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
      pwm.pinDuty( 7, pwm_duty );  // 75% duty cycle on Pin 7
      break;

    case 5:  //VENTOLA SX_2 DX_3
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 50% duty cycle on Pin 6
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 75% duty cycle on Pin 7
      break;

    case 6:  //VENTOLA SX_3 DX_2
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 50% duty cycle on Pin 7
      break;

    case 7: //VENTOLA SX_2 DX_0
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 50% duty cycle on Pin 6
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 0% duty cycle on Pin 7
      break;

    case 8: //VENTOLA SX_0 DX_2
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 0% duty cycle on Pin 6
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 50% duty cycle on Pin 7
      break;

    case 9:  //VENTOLA SX_2 DX_2
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 50% duty cycle on Pin 6
      pwm.pinDuty( 7, pwm_duty );  // 50% duty cycle on Pin 7
      break;

    case 10:  //VENTOLA SX_1 DX_2
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 25% duty cycle on Pin 6
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 50% duty cycle on Pin 7
      break;

    case 11:  //VENTOLA SX_2 DX_1
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 50% duty cycle on Pin 6
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 25% duty cycle on Pin 7
      break;

    case 12: //VENTOLA SX_1 DX_1
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 25% duty cycle on Pin 6
      pwm.pinDuty( 7, pwm_duty );  // 25% duty cycle on Pin 7
      break;

    case 13:  //VENTOLA SX_0 DX_1
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 0% duty cycle on Pin 6
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 25% duty cycle on Pin 7
      break;

    case 14: //VENTOLA SX_1 DX_0
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 25% duty cycle on Pin 6
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 0% duty cycle on Pin 7
      break;

    case 15:  //VENTOLA SX_3 DX_1
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 25% duty cycle on Pin 7
      break;

    case 16:  //VENTOLA SX_1 DX_3
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 25% duty cycle on Pin 6
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 75% duty cycle on Pin 7
      break;

    default:

      break;
  }
}
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Aug 13, 2018, 10:26 pm
Buonasera,
dato che ora che leggo nel modo corretto la LIN la stringa che devo leggere è molto più semplice ho provato a riscrivere il codice.
Non mi da errori di compilazione ma le ventole non girano o meglio si mettono a girare quando vogliono solo al massimo della velocità.
Ho bisogno del vostro aiuto:


Code: [Select]


// CODICE RILEVAZIONE EVENTI SU LINBUS LEXUS e COMANDO VENTOLE PWM

#include <DuePWM.h>
#define PIN_CS 2
#define PIN_FAULT 9
#define PWM_FREQ1  20000
#define PWM_FREQ2  20000
uint32_t pwm_duty = 255; // 255 = 0% duty cycle
DuePWM pwm( PWM_FREQ1, PWM_FREQ2 );
byte comando;
byte last_comando;
static byte trovato[3] = { 0, 0, 0 };
byte actuallyRead;
unsigned long lastRx;

void setup(void)
{
  pinMode(PIN_CS, OUTPUT);
  pinMode(PIN_FAULT, OUTPUT);
  digitalWrite(PIN_CS, HIGH);
  digitalWrite(PIN_FAULT, LOW);
  Serial.begin(9600); //debug serial
  Serial.println("Due debug Comms");
  Serial2.begin(9600); //LIN Serial Rx
  pwm.setFreq1( PWM_FREQ1 );
  pwm.setFreq2( PWM_FREQ2 );
  pwm.pinFreq1( 6 );  // Pin 6 Vent SX freq set to "pwm_freq1" on clock A
  pwm.pinFreq2( 7 );  // Pin 7 Vent DX freq set to "pwm_freq2" on clock B
  comando = 0x0;
  last_comando = 0x0;
}
void loop(void)
{
label:
  if ((millis() - lastRx) > 500)
  {
    if (Serial2.available())
    {
      actuallyRead = Serial2.read();
      lastRx = millis();
      //Serial.println(actuallyRead, HEX); //qui leggo correttamente la LIN
      if (actuallyRead == 0x55)
      {
        trovato[1] = 0x55;
        actuallyRead = Serial2.read();
        lastRx = millis();
        if (actuallyRead == 0x78)
        {
          trovato[2] = 0x78;
          actuallyRead = Serial2.read();
          lastRx = millis();
          if (actuallyRead == 0x0)
          {
            trovato[3] = 0x0;
            byte comando = Serial2.read();
            lastRx = millis();
            if ( comando != last_comando)
            {
              void Switch_Case_Comando ();
            }
            else
            {
              goto label;
            }
          }
          else
          {
            goto label;
          }
        }
        else
        {
          goto label;
        }
      }
      else
      {
        goto label;
      }
    }
    else
    {
      goto label;
    }
  }
}



Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Aug 14, 2018, 11:04 am
Il secondo pezzo:

Code: [Select]

void Switch_Case_Comando ()
{
  switch (comando)
  {
    case 0x0 : //TUTTO SPENTO
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 0% duty cycle on Pin 6
      pwm.pinDuty( 7, pwm_duty );  // 0% duty cycle on Pin 7
      break;

    case 0xB :  //VENTOLA SX_3 DX_0
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 0% duty cycle on Pin 7
      break;

    case 0xB0:  //VENTOLA SX_0 DX_3
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 0% duty cycle on Pin 6
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 75% duty cycle on Pin 7
      break;

    case 0xBB: //VENTOLA SX_3 DX_3
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
      pwm.pinDuty( 7, pwm_duty );  // 75% duty cycle on Pin 7
      break;

    case 0xBA:  //VENTOLA SX_2 DX_3
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 50% duty cycle on Pin 6
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 75% duty cycle on Pin 7
      break;

    case 0xAB:  //VENTOLA SX_3 DX_2
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 50% duty cycle on Pin 7
      break;

    case 0xA: //VENTOLA SX_2 DX_0
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 50% duty cycle on Pin 6
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 0% duty cycle on Pin 7
      break;

    case 0xA0: //VENTOLA SX_0 DX_2
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 0% duty cycle on Pin 6
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 50% duty cycle on Pin 7
      break;

    case 0xAA:  //VENTOLA SX_2 DX_2
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 50% duty cycle on Pin 6
      pwm.pinDuty( 7, pwm_duty );  // 50% duty cycle on Pin 7
      break;

    case 0xA9:  //VENTOLA SX_1 DX_2
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 25% duty cycle on Pin 6
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 50% duty cycle on Pin 7
      break;

    case 0x9A:  //VENTOLA SX_2 DX_1
      pwm_duty = 130; // 50% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 50% duty cycle on Pin 6
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 25% duty cycle on Pin 7
      break;

    case 0x99: //VENTOLA SX_1 DX_1
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 25% duty cycle on Pin 6
      pwm.pinDuty( 7, pwm_duty );  // 25% duty cycle on Pin 7
      break;

    case 0x90:  //VENTOLA SX_0 DX_1
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 0% duty cycle on Pin 6
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 25% duty cycle on Pin 7
      break;

    case 0x9: //VENTOLA SX_1 DX_0
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 25% duty cycle on Pin 6
      pwm_duty = 255; // 0% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 0% duty cycle on Pin 7
      break;

    case 0x9B:  //VENTOLA SX_3 DX_1
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 75% duty cycle on Pin 6
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 25% duty cycle on Pin 7
      break;

    case 0xB9:  //VENTOLA SX_1 DX_3
      pwm_duty = 200; // 25% duty cycle
      pwm.pinDuty( 6, pwm_duty );  // 25% duty cycle on Pin 6
      pwm_duty = 70; // 75% duty cycle
      pwm.pinDuty( 7, pwm_duty );  // 75% duty cycle on Pin 7
      break;

    default:

      break;
  }
}
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Aug 16, 2018, 12:01 pm
Buongiorno a tutti,

se io scrivo:

Code: [Select]

  if (Serial2.available())
  {
    inByte = Serial2.read ();

    if (inByte == 0x55)
    {
      i = 0;
      messaggio [0] = inByte;
      inByte = Serial2.read ();
      for (i = 0; i < 12; i++)
        messaggio [i] = inByte ;
      Serial.println ( messaggio [i], HEX);
      if (messaggio[0] == 0x55 && messaggio[1] == 0x78 && messaggio[2] == 0x0 )
      {
        comando = messaggio[3];



nell'array messaggio 0 avrò il byte 0x55 e a seguire quelli che legge successivamente?
Title: Re: Comandare ventola PWM con LIN BUS
Post by: PM68 on Sep 17, 2018, 09:54 am
Buongiorno a tutti,
il progetto è concluso e funziona perfettamente.
Pubblico il codice definitivo per chi è interessato:

Code: [Select]

// CODICE RILEVAZIONE EVENTI SU LINBUS LEXUS e COMANDO VENTOLE PWM

#define PIN_CS 2
#define PIN_FAULT 9
#define V_SX 6
#define V_DX 7

int V0 = 255;
int V1 = 170;
int V2 = 85;
int V3 = 0;

byte stato = 0;
byte comando;

void setup()
{
  pinMode(PIN_CS, OUTPUT);
  pinMode(PIN_FAULT, OUTPUT);
  pinMode(V_SX, OUTPUT);
  pinMode(V_DX, OUTPUT);
  digitalWrite(PIN_FAULT, HIGH);
  analogWrite( V_SX , V0 ); //VENTOLA Sx FERMA
  analogWrite( V_DX , V0 ); //VENTOLA Dx FERMA
  //Serial.begin(57600); //debug serial
  //Serial.println("Due debug Comms");
  Serial3.begin(9600); //LIN Serial Rx
  digitalWrite(PIN_CS, HIGH);
}

void loop()

{
  while (Serial3.available())
  {
    byte rx = Serial3.read();
    //Serial.println (rx , HEX);
    switch (stato)
    {
      case 0:
        if (rx == 0x55)      stato = 1;
        else                 stato = 0;
        break;
      case 1:
        if (rx == 0x78)      stato = 2;
        else if (rx == 0x55) stato = 1;
        else                 stato = 0;
        break;
      case 2:
        if (rx == 0x00)      stato = 3;
        else if (rx == 0x55) stato = 1;
        else                 stato = 0;
        break;
      case 3:
        if (rx == 0x55)      stato = 1;
        else {
          switch (rx)
          {
            case 0x0 : // 0x0 TUTTO SPENTO
              analogWrite( 6, V0 );
              analogWrite( 7, V0 );
              break;

            case 0xB :  // 0xB VENTOLA SX_3 DX_0
              analogWrite( 6, V3 );
              analogWrite( 7, V0 );
              break;

            case 0x7B :  // 0x7B VENTOLA SX_3 DX_0 RISC Dx_3
              analogWrite( 6, V3 );
              analogWrite( 7, V0 );
              break;

            case 0x6B :  // 0x6B VENTOLA SX_3 DX_0 RISC Dx_2
              analogWrite( 6, V3 );
              analogWrite( 7, V0 );
              break;

            case 0x5B :  // 0x5B VENTOLA SX_3 DX_0 RISC Dx_1
              analogWrite( 6, V3 );
              analogWrite( 7, V0 );
              break;

            case 0xB0 :  // 0xB0 VENTOLA SX_0 DX_3
              analogWrite( 6, V0 );
              analogWrite( 7, V3 );
              break;

            case 0xB7 :  // 0xB7 VENTOLA SX_0 DX_3 RISC Sx_3
              analogWrite( 6, V0 );
              analogWrite( 7, V3 );
              break;

            case 0xB6 :  // 0xB6 VENTOLA SX_0 DX_3  RISC Sx_2
              analogWrite( 6, V0 );
              analogWrite( 7, V3 );
              break;

            case 0xB5 :  // 0xB5 VENTOLA SX_0 DX_3 RISC Sx_1
              analogWrite( 6, V0 );
              analogWrite( 7, V3 );
              break;

            case 0xBB : // 0xBB VENTOLA SX_3 DX_3
              analogWrite( 6, V3 );
              analogWrite( 7, V3 );
              break;

            case 0xBA :  // 0xBA VENTOLA SX_2 DX_3
              analogWrite( 6, V2 );
              analogWrite( 7, V3 );
              break;

            case 0xAB :  // 0xAB VENTOLA SX_3 DX_2
              analogWrite( 6, V3 );
              analogWrite( 7, V2 );
              break;

            case 0xA : // 0xA VENTOLA SX_2 DX_0
              analogWrite( 6, V2 );
              analogWrite( 7, V0 );
              break;

            case 0x7A :  // 0x7A VENTOLA SX_2 DX_0 RISC Dx_3
              analogWrite( 6, V2 );
              analogWrite( 7, V0 );
              break;

            case 0x6A :  // 0x6A VENTOLA SX_2 DX_0 RISC Dx_2
              analogWrite( 6, V2 );
              analogWrite( 7, V0 );
              break;

            case 0x5A :  // 0x5A VENTOLA SX_2 DX_0 RISC Dx_1
              analogWrite( 6, V2 );
              analogWrite( 7, V0 );
              break;

            case 0xA0 : // 0xA0 VENTOLA SX_0 DX_2
              analogWrite( 6, V0 );
              analogWrite( 7, V2 );
              break;

            case 0xA7 : // 0xA7 VENTOLA SX_0 DX_2 RISC Sx_3
              analogWrite( 6, V0 );
              analogWrite( 7, V2 );
              break;

            case 0xA6 : // 0xA6 VENTOLA SX_0 DX_2 RISC Sx_2
              analogWrite( 6, V0 );
              analogWrite( 7, V2 );
              break;

            case 0xA5 : // 0xA5 VENTOLA SX_0 DX_2 RISC Sx_1
              analogWrite( 6, V0 );
              analogWrite( 7, V2 );
              break;

            case 0xAA :  // 0xAA VENTOLA SX_2 DX_2
              analogWrite( 6, V2 );
              analogWrite( 7, V2 );
              break;

            case 0xA9 :  // 0xA9 VENTOLA SX_1 DX_2
              analogWrite( 6, V1 );
              analogWrite( 7, V2 );
              break;

            case 0x9A :  // 0x9A VENTOLA SX_2 DX_1
              analogWrite( 6, V2 );
              analogWrite( 7, V1 );
              break;

            case 0x99 : // 0x99 VENTOLA SX_1 DX_1
              analogWrite( 6, V1 );
              analogWrite( 7, V1 );
              break;

            case 0x90 :  // 0x90 VENTOLA SX_0 DX_1
              analogWrite( 6, V0 );
              analogWrite( 7, V1 );
              break;

            case 0x9 : // 0x9 VENTOLA SX_1 DX_0
              analogWrite( 6, V1 );
              analogWrite( 7, V0 );
              break;

            case 0x79 :  // 0x79 VENTOLA SX_1 DX_0 RISC Dx_3
              analogWrite( 6, V1 );
              analogWrite( 7, V0 );
              break;

            case 0x69 :  // 0x69 VENTOLA SX_1 DX_0 RISC Dx_2
              analogWrite( 6, V1 );
              analogWrite( 7, V0 );
              break;

            case 0x59 :  // 0x59 VENTOLA SX_1 DX_0 RISC Dx_1
              analogWrite( 6, V1 );
              analogWrite( 7, V0 );
              break;

            case 0x9B :  // 0x9B VENTOLA SX_3 DX_1
              analogWrite( 6, V3 );
              analogWrite( 7, V1 );
              break;

            case 0xB9 :  // 0xB9 VENTOLA SX_1 DX_3
              analogWrite( 6, V1 );
              analogWrite( 7, V3 );
              break;

            case 0x7 :  // 0x7 VENTOLA SX_0 DX_0 RISC SX_3 DX_0
              analogWrite( 6, V0 );
              analogWrite( 7, V0 );
              break;

            case 0x6 :  // 0x6 VENTOLA SX_0 DX_0 RISC SX_2 DX_0
              analogWrite( 6, V0 );
              analogWrite( 7, V0 );
              break;

            case 0x5 :  // 0x5 VENTOLA SX_0 DX_0 RISC SX_1 DX_0
              analogWrite( 6, V0 );
              analogWrite( 7, V0 );
              break;

            case 0x97 :  // 0x97 VENTOLA SX_0 DX_1
              analogWrite( 6, V0 );
              analogWrite( 7, V1 );
              break;

            case 0x70 :  // 0x70 VENTOLA SX_0 DX_0  RISC SX_0 DX_3
              analogWrite( 6, V0 );
              analogWrite( 7, V0 );
              break;

            case 0x60 :  // 0x60 VENTOLA SX_0 DX_0  RISC SX_0 DX_2
              analogWrite( 6, V0 );
              analogWrite( 7, V0 );
              break;

            case 0x50 :  // 0x50 VENTOLA SX_0 DX_0  RISC SX_0 DX_1
              analogWrite( 6, V0 );
              analogWrite( 7, V0 );
              break;

            default:
              break;
          }
          stato = 0;
        }
    }
  }
}