Driver CH340 non riconosciuto da alcune schede NANO

Non esegue il codice correttamente.

Se non avete il pcb con arduino montato non posso spiegarvelo.
Non so nemmeno come spiegarvelo.
Il problema è sul convertitore, ma non so cosa.
Speravo che ad uno del forum fosse capitato una cosa analoga, con un altro codice e stesso NANO, ma vedo che è una cos abbastanza isolata.

Problema (che non ho un idea come presenta) può essere correlato al convertitore, oppure no.

void setup()
{
  Serial.end();
  //Serial.begin(57000);

Perche' Serial è stata disabilitata ma codice lo chiama continuamente? E perche baudrate era 57000 invece di 57600?

Confermi che hai provato entrambi bootloader:

  • ATmega328P
  • ATmega328P (Old Bootloader)

ps. ci sono anche cloni con processore diverso da 328P, hai verificato?

Ma un minimo di punteggiatura?

Questa tua frase è ambigua.

Impara ad essere chiaro, che ti aiuterà di certo

Comunque se il micro si programma col Blink la seriale va, senza se e senza ma

Bisogna vedere il programma

Mettilo in chiaro: io non scarico file foresti

Anche la storia dei bottloader è una pippa:

Se con un qualsiasi boot-loader il Blink va sappiamo quale boot-loader usare su quella scheda, ora e sempre

1 Like

Ecco qua il programma in chiaro:

#include <LocoNet.h>
#include <EEPROM.h>

#define LnTXpin 11    //Receive LocoNet PIN

// Item Number (Art.-Nr.): 63340
#define ARTNR 6334
#define generalAdr 65535  //General-Adresse 0xFFFF

static  lnMsg        *LnPacket;
static  LnBuf        LnTxBuffer;

#define maxLNCV 100 //lesbare LNCV
#define dAnz 8    //Anzahl der Eingänge
#define MaxAdr 4096    //höchste nutzbare Adresse

byte dPin[dAnz] = {2, 3, 4, 5, 6, 7, 9, 10};

#define ProgSwPin 12      //Programmiertaster
#define LedPin 13         //status LED

unsigned int dAdr[dAnz];

//Entprellen der Eingänge, LNCV EEPROM:
#define timefalling 21  //LNCV val = 0; Verzögerung der Rückmeldung HIGH -> LOW (BELEGT)
#define defaultfall 0
#define timerising 41  //LNCV val = 200;    //Verzögerung der Rückmeldung LOW -> HIGH (FREI)
#define defaultrise 200

#define reportAdr 17  //LNCV val = 1017;  //Ausgabe der Zustände der Rückmelder
#define defaultreport 1017  

unsigned int dtime[dAnz];
boolean dstate[dAnz];

int count = -1;    //Zähler für PIN Abfrage, beginne bei 0
unsigned int LedCount = 0;

boolean SwState = false;
boolean ProgAdr = false;

LocoNetCVClass lnCV;
boolean programmingMode = false;

void setup()
{
  Serial.end();
  //Serial.begin(57600);
  
  // First initialize the LocoNet interface
  LocoNet.init(LnTXpin);
  
  pinMode(ProgSwPin, INPUT_PULLUP);
  pinMode(LedPin, OUTPUT);
  digitalWrite(LedPin, LOW);    //LED off
  
  //Adresse aus LNCV lesen:
  unsigned int Adresse = lncv(0);
  if (Adresse > (MaxAdr - dAnz)) {
    Adresse = 1;
    lncv(0,1);    //default Values
    lncv(timefalling, defaultfall);
    lncv(timerising, defaultrise);
    lncv(reportAdr, defaultreport);
  }
  if (lncv(timefalling) > 60000)
    lncv(timefalling, defaultfall);
  if (lncv(timerising) > 60000)
    lncv(timerising, defaultrise);  
  
  //Initialisierung der Eingänge
  for (int i = 0; i < dAnz; i++) {
    //set ADR:
    dAdr[i] = Adresse + i;    //fortlaufende Adressen
    //set default state:
    dtime[i] = 0;
    dstate[i] = false;
    pinMode(dPin[i], INPUT_PULLUP);       //Pin auf Eingang & Pullup aktivieren
    if (dstate[i] == digitalRead(dPin[i])) {    //Vorbelegung setzten!
      dstate[i] = true;
      //sendSensor(dAdr[i], true);     //aktuellen Status senden - ON
      digitalWrite(LedPin, HIGH);    //LED on
    }
  }
}

void loop()
{  
  // Check for any received LocoNet packets
  LnPacket = LocoNet.receive();

  if( LnPacket )
  {
      // First print out the packet in HEX
    Serial.print("RX: ");
    uint8_t msgLen = getLnMsgSize(LnPacket); 
    for (uint8_t x = 0; x < msgLen; x++)
    {
      uint8_t val = LnPacket->data[x];
        // Print a leading 0 if less than 16 to make 2 HEX digits
      if(val < 16)
        Serial.print('0');
        
      Serial.print(val, HEX);
      Serial.print(' ');
    }  
    // If this packet was not a Switch or Sensor Message then print a new line 
    uint8_t packetConsumed(LocoNet.processSwitchSensorMessage(LnPacket));
    if (packetConsumed == 0) {
      Serial.println();
      packetConsumed = lnCV.processLNCVMessage(LnPacket);
    }
  }

  //handle programming switch:
  if (SwState == false && digitalRead(ProgSwPin) == LOW) {
    //down
    SwState = true;
  }
  if (SwState == true && digitalRead(ProgSwPin) == HIGH) {
    //up
    SwState = false;
    ProgAdr = !ProgAdr;
  }
  
  //toggle status LED:
  LedCount++;
  if (LedCount > 1700) {
      LedCount = 0;
    
    if (ProgAdr == true) {  //Blinken bei Programmierung
      digitalWrite(LedPin, !digitalRead(LedPin));  //change
    }
    else {
    digitalWrite(LedPin, LOW);    //show LocoNet send feedback Data
    }
  }
  //handle input states:
  count++;    //nächsten Input Abfragen
  if (count >= dAnz)    //Max Input prüfen
    count = 0;        //beim Ersten beginnen
  if (dstate[count] != digitalRead(dPin[count])) {  //Eingang hat sich geändert?
    dtime[count]++;
    digitalWrite(LedPin, HIGH);    //LED on
    if ((dstate[count] == true) && (dtime[count] >= lncv(timefalling))) {    //falling (high -> low)
       sendSensor(dAdr[count], true);     //aktuellen Status senden - ON
       dstate[count] = !dstate[count];             //Speicher aktualisieren
       dtime[count] = 0;
    }
    else if ((dstate[count] == false) && (dtime[count] >= lncv(timerising))) {     //rising (low -> high)
       sendSensor(dAdr[count], false);     //aktuellen Status senden - OFF
       dstate[count] = !dstate[count];             //Speicher aktualisieren
       dtime[count] = 0;     
    }
  }
}

// Rückmeldesonsor Daten senden
void sendSensor(int Adr, boolean state) {
  //Adressen von 1 bis 4096 (MaxAdr) akzeptieren
  if (Adr <= 0)        //nur korrekte Adressen
    return;
  Adr = Adr - 1;    
  byte D2 = Adr >> 1;    //Adresse Teil 1 erstellen
  bitWrite(D2,7,0);        //A1 bis A7
    
  byte D3 = Adr >> 8;     //Adresse Teil 2 erstellen, A8 bis A11
  bitWrite(D3,4, state);    //Zustand ausgeben
  bitWrite(D3,5,bitRead(Adr,0));    //Adr Bit0 = A0
    
  //Checksum bestimmen:  
  byte D4 = 0xFF;        //Invertierung setzten
  D4 = OPC_INPUT_REP ^ D2 ^ D3 ^ D4;  //XOR
  bitWrite(D4,7,0);     //MSB Null setzten
  
  addByteLnBuf( &LnTxBuffer, OPC_INPUT_REP ) ;    //0xB2
  addByteLnBuf( &LnTxBuffer, D2 ) ;    //1. Daten Byte IN2
  addByteLnBuf( &LnTxBuffer, D3 ) ;    //2. Daten Byte IN2
  addByteLnBuf( &LnTxBuffer, D4 ) ;    //Prüfsumme
  addByteLnBuf( &LnTxBuffer, 0xFF ) ;    //Trennbit

        // Check to see if we have received a complete packet yet
  LnPacket = recvLnMsg( &LnTxBuffer );    //Senden vorbereiten
  if(LnPacket ) {        //korrektheit Prüfen
    LocoNet.send( LnPacket );  // Send the received packet from the PC to the LocoNet
  }  
}

  // This call-back function is called from LocoNet.processSwitchSensorMessage
  // for all Switch Request messages
void notifySwitchRequest( uint16_t Address, uint8_t Output, uint8_t Direction ) {
  Serial.print("Switch Report: ");
  Serial.print(Address, DEC);
  Serial.print(':');
  Serial.print(Direction ? "Closed" : "Thrown");
  Serial.print(" - ");
  Serial.println(Output ? "On" : "Off");
  
  unsigned int Adr = lncv(0);
  if (ProgAdr == true) {
    digitalWrite(LedPin, HIGH);    //LED on
    Serial.println("neue Adresse!");
    Adr = Address;
    lncv(0, Address);
    lncv(timefalling, defaultfall);
    lncv(timerising, defaultrise); 
    lncv(reportAdr, defaultreport); 
    //Reset Adressen:
    for (int i = 0; i < dAnz; i++) {
      //set ADR:
      dAdr[i] = Adr + i;    //fortlaufende Adressen
    }
    ProgAdr = false;
  }

  if (Address == lncv(reportAdr) && Output == 0) {
    //alle Eingänge melden:
    for (int i = 0; i < dAnz; i++) {
      sendSensor(dAdr[i], !dstate[i]);     //aktuellen Status senden
    }
  }
}

  // This call-back function is called from LocoNet.processSwitchSensorMessage
  // for all Sensor messages
void notifySensor( uint16_t Address, uint8_t State ) {
  Serial.print("Sensor: ");
  Serial.print(Address, DEC);
  Serial.print(" - ");
  Serial.println( State ? "Active" : "Inactive" );
}

  /**
   * Notifies the code on the reception of a read request.
   * Note that without application knowledge (i.e., art.-nr., module address
   * and "Programming Mode" state), it is not possible to distinguish
   * a read request from a programming start request message.
   */
int8_t notifyLNCVread(uint16_t ArtNr, uint16_t lncvAddress, uint16_t,
    uint16_t & lncvValue) {
  Serial.print("Enter notifyLNCVread(");
  Serial.print(ArtNr, HEX);
  Serial.print(", ");
  Serial.print(lncvAddress, HEX);
  Serial.print(", ");
  Serial.print(", ");
  Serial.print(lncvValue, HEX);
  Serial.print(")");
  // Step 1: Can this be addressed to me?
  // All ReadRequests contain the ARTNR. For starting programming, we do not accept the broadcast address.
  if (programmingMode) {
    if (ArtNr == ARTNR) {
      if (lncvAddress < maxLNCV) {
        lncvValue = lncv(lncvAddress);
        Serial.print(" LNCV Value: ");
        Serial.print(lncvValue);
        Serial.print("\n");
        return LNCV_LACK_OK;
      } else {
        // Invalid LNCV address, request a NAXK
        return LNCV_LACK_ERROR_UNSUPPORTED;
      }
    } else {
      Serial.print("ArtNr invalid.\n");
      return -1;
    }
  } else {
    Serial.print("Ignoring Request.\n");
    return -1;
  }
}

int8_t notifyLNCVprogrammingStart(uint16_t & ArtNr, uint16_t & ModuleAddress) {
  // Enter programming mode. If we already are in programming mode,
  // we simply send a response and nothing else happens.
  Serial.print("notifyLNCVProgrammingStart ");
  if (ArtNr == ARTNR) {
    Serial.print("artnrOK ");
    if (ModuleAddress == lncv(0)) {
      Serial.print("moduleUNI ENTERING PROGRAMMING MODE\n");
      programmingMode = true;
      return LNCV_LACK_OK;
    } else if (ModuleAddress == generalAdr) {
      Serial.print("moduleBC ENTERING PROGRAMMING MODE\n");
      ModuleAddress = lncv(0);
      programmingMode = true;
      return LNCV_LACK_OK;
    }
  }
  Serial.print("Ignoring Request.\n");
  return -1;
}

  /**
   * Notifies the code on the reception of a write request
   */
int8_t notifyLNCVwrite(uint16_t ArtNr, uint16_t lncvAddress,
    uint16_t lncvValue) {
  Serial.print("notifyLNCVwrite, ");
  //  dumpPacket(ub);
  if (!programmingMode) {
    Serial.print("not in Programming Mode.\n");
    return -1;
  }

  if (ArtNr == ARTNR) {
    Serial.print("Artnr OK, ");

    if (lncvAddress < maxLNCV) {
      lncv(lncvAddress, lncvValue);
      return LNCV_LACK_OK;
    }
    else {
      return LNCV_LACK_ERROR_UNSUPPORTED;
    }

  }
  else {
    Serial.print("Artnr Invalid.\n");
    return -1;
  }
}

  /**
   * Notifies the code on the reception of a request to end programming mode
   */
void notifyLNCVprogrammingStop(uint16_t ArtNr, uint16_t ModuleAddress) {
  Serial.print("notifyLNCVprogrammingStop ");
  if (programmingMode) {
    if (ArtNr == ARTNR && ModuleAddress == lncv(0)) {
      programmingMode = false;
      Serial.print("End Programing Mode.\n");
    }
    else {
      if (ArtNr != ARTNR) {
        Serial.print("Wrong Artnr.\n");
        return;
      }
      if (ModuleAddress != lncv(0)) {
        Serial.print("Wrong Module Address.\n");
        return;
      }
    }
  }
  else {
    Serial.print("Ignoring Request.\n");
  }
}

//write LNCV into EEPROM:
void lncv (uint16_t Adr, uint16_t val) {
  unsigned int Address = Adr * 2;
  EEPROM.update(Address, val & 0xFF);   //LSB
  EEPROM.update(Address + 1, val >> 8); //MSB
}
//read LNCV from EEPROM
uint16_t lncv (uint16_t Adr) {
  unsigned int Address = Adr * 2;
  unsigned int val = 0;
  val = (EEPROM.read(Address) & 0xFF) | ((EEPROM.read(Address + 1) & 0xFF) << 8);   //LSB & MSB
  return val;
}

Provato i due boot ma niente.
Il nano marchiato viene riconosciuto sulla COM3, carica il codice con il boot più recente e funziona.
Il nano anonimo viene riconosciuto sulla COM4, carica con l'old bootloader e non funziona.

Potresti rispondere le domande o indichi chiaramente che non sei interessato...

Perdona, ma ... come ti è stato detto, questo che segue NON ha molto senso ...

... utilizzi in continuazione la seriale, ma non fai mai, in modo esplicito, una sua corretta inizializzazione :roll_eyes:

Viene forse fatta da qualche altra parte? In qualche libreria? Se SI, con che parametri?

Guglielmo

Il programma non l'ho scritto io non so nemmeno come si fa.
Non lo so leggere non posso darvi queste info.
Mi chiedete cose al di fuori delle mie conoscenze.
Ripeto, ho questo codice scaricato da internet che su alcuni NANO funziona su altri no.
Sono ignorante lo ammetto, ma non conosco la programmazione.

Su alcuni clone funziona, alcuni no.
Se originale costa 20eur e clone piu' economico meno di 2, pensi che sono tutti uguali?
Ancora non hai risposto nemmeno cosa c'e' scritto sul processore. Forse nemmeno 328P.
Tuo progetto mi sembra abbastanza sensibile a timing preciso, anche piccoli dettagli possono creare problemi.

Quoto in pieno

Comunque lo Op deve abilitare la seriale

Non è un mio progetto !!!!
Sul processore cè scritto MEGA328PB sia su quello che funziona che su quello che non funziona.
Caro kmin ma almeno leggi tutto il post.
Distinguere un 168 da un 328 ce la faccio.
Ad oggi tutti i cloni mi hanno funzionato questi no.
Sono differenti dagli originali ? Certo, a me vanno bene per quello che devo fare.

Ma come si quota in questo forum?

Se hanno il timing svaccato non sono adatti

Infatti non vanno, mi sembra

Comunque adesso sappiamo che la seriale non dovrebbe centrare

Ok ma perchè gli altri funzionano correttamente ?
Sono sempre cloni.

Nano con un 328PB??? :thinking: Mi sembra strano ... al limite 328P ... il 328PB è altra cosa. Le NANO v3 Arduino (e relativi cloni) al limite montano il PU ... se tu hai dei cloni con il 328PB devi cambiare "core" ... non puoi programmare un PB come un P o PU :roll_eyes:

Fai una foto ben visibile della MCU che verifichiamo il tipo esatto ...

Guglielmo

Ho letto.
E ho chiesto perche avevo dubbi anche dopo letto..
328P, 328PB, LGT8F328P...

Hai un link a dove li hai comprati?

Guglielmo

Preciso ho dei nano con 328P e sono quelli che funzionano mentre quelli con il 328PB non funzionano. Il link è qualche messaggio sopra.


Pero' non sono uguali e causano tua problema qui. Perche' vuoi credere che viene da chip usb-serial?

Perchè era il componente diverso fino a 5 min fa.
Poi Guglielmo mi ha fatto notare il 328 P/PB e ci ho guardato.
Ne avrò comprati 100 mai successo questo problema.

Per i Nano 328P puoi usare il "core" Arduino Nano V3, mentre per i 328PB devi installare il MiniCore che ti permette di selezionare ATmega328PB e ne sfrutta le caratteristiche.

Guglielmo

Grazie Guglielmo,

scaricato adesso.
ora devo capire come installare il minicore.
E' un integrazione dell'IDE ?