Convertire un codice ldmicro in codice per IDE

In un forum di Elettronica mi è stato fornito questo codice che dovrebbe risolvermi un problema di controllo di un sensore per un allarme, che mi sta facendo spazientire ]:smiley:
Il codice è per il free software LDMicro che, tra le altre cose, prevede la possibilità di programmare chip della ATMEL (ma il 328 non c'è) e comunque di salvare il codice in C; purtoppo non riesco a capire come si usa questo programma.
Qualcuno che lo usa potrebbe gentilmente farmi questa conversione e postarmi la versione IDE-compatibile (o quasi...)?

LDmicro0.1 
CYCLE=10000 
CRYSTAL=4000000 
BAUD=2400 

IO LIST 
Xnew at 0 
Yrf at 0 
END 

PROGRAM 
RUNG 
CONTACTS Xnew 0 
OSF 
PARALLEL 
COIL Rnew 0 1 0 
COIL Rdue 0 0 0 
END 
END 
RUNG 
CONTACTS Rnew 0 
TON Tdel 100000 
COIL Rout 0 0 0 
END 
RUNG 
CONTACTS Rout 0 
TON Tnew 5000000 
COIL Rnew 0 0 1 
END 
RUNG 
CONTACTS Rdue 0 
CONTACTS Rout 0 
COIL Ruscita 0 1 0 
END 
RUNG 
CONTACTS Ruscita 0 
TON Ton_rf 500000 
COIL Ruscita 0 0 1 
END 
RUNG 
CONTACTS Ruscita 0 
COIL Yrf 0 0 0 
END

Non conoscendo il linguaggio, non so cosa dovrebbe fare quella porzione di codice.
E senza sapere questo, è difficile tradurre tale codice in codice per Arduino.

Il codice è scritto in Ladder, un linguaggio per plc, probabilmente hai avuto difficoltà per il formato in input che deve seguire alcune semplici regole, eccoti la conversione in C che esegue microladder, a mio avviso totalmente inutile :slight_smile:
Se ci dici che sensore stai usando magari è possibile darti un aiuto.

/* This is auto-generated code from LDmicro. Do not edit this file! Go
   back to the ladder diagram source for changes in the logic, and make
   any C additions either in ladder.h or in additional .c files linked
   against this one. */

/* You must provide ladder.h; there you must provide:
      * a typedef for SWORD and BOOL, signed 16 bit and boolean types
        (probably typedef signed short SWORD; typedef unsigned char BOOL;)

   You must also provide implementations of all the I/O read/write
   either as inlines in the header file or in another source file. (The
   I/O functions are all declared extern.)

   See the generated source code (below) for function names. */
#include "ladder.h"

/* Define EXTERN_EVERYTHING in ladder.h if you want all symbols extern.
   This could be useful to implement `magic variables,' so that for
   example when you write to the ladder variable duty_cycle, your PLC
   runtime can look at the C variable U_duty_cycle and use that to set
   the PWM duty cycle on the micro. That way you can add support for
   peripherals that LDmicro doesn't know about. */
#ifdef EXTERN_EVERYTHING
#define STATIC 
#else
#define STATIC static
#endif

/* Define NO_PROTOTYPES if you don't want LDmicro to provide prototypes for
   all the I/O functions (Read_U_xxx, Write_U_xxx) that you must provide.
   If you define this then you must provide your own prototypes for these
   functions in ladder.h, or provide definitions (e.g. as inlines or macros)
   for them in ladder.h. */
#ifdef NO_PROTOTYPES
#define PROTO(x)
#else
#define PROTO(x) x
#endif

/* U_xxx symbols correspond to user-defined names. There is such a symbol
   for every internal relay, variable, timer, and so on in the ladder
   program. I_xxx symbols are internally generated. */
STATIC BOOL I_b_mcr = 0;
#define Read_I_b_mcr() I_b_mcr
#define Write_I_b_mcr(x) I_b_mcr = x
STATIC BOOL I_b_rung_top = 0;
#define Read_I_b_rung_top() I_b_rung_top
#define Write_I_b_rung_top(x) I_b_rung_top = x

/* You provide this function. */
PROTO(extern BOOL Read_U_b_Xnew(void);)

STATIC BOOL I_b_scratch = 0;
#define Read_I_b_scratch() I_b_scratch
#define Write_I_b_scratch(x) I_b_scratch = x
STATIC BOOL I_b_oneShot_0000 = 0;
#define Read_I_b_oneShot_0000() I_b_oneShot_0000
#define Write_I_b_oneShot_0000(x) I_b_oneShot_0000 = x
STATIC BOOL I_b_parOut_0000 = 0;
#define Read_I_b_parOut_0000() I_b_parOut_0000
#define Write_I_b_parOut_0000(x) I_b_parOut_0000 = x
STATIC BOOL I_b_parThis_0000 = 0;
#define Read_I_b_parThis_0000() I_b_parThis_0000
#define Write_I_b_parThis_0000(x) I_b_parThis_0000 = x
STATIC BOOL U_b_Rnew = 0;
#define Read_U_b_Rnew() U_b_Rnew
#define Write_U_b_Rnew(x) U_b_Rnew = x
STATIC BOOL U_b_Rdue = 0;
#define Read_U_b_Rdue() U_b_Rdue
#define Write_U_b_Rdue(x) U_b_Rdue = x
STATIC SWORD U_i_Tdel = 0;
STATIC BOOL U_b_Rout = 0;
#define Read_U_b_Rout() U_b_Rout
#define Write_U_b_Rout(x) U_b_Rout = x
STATIC SWORD U_i_Tnew = 0;
STATIC BOOL U_b_Ruscita = 0;
#define Read_U_b_Ruscita() U_b_Ruscita
#define Write_U_b_Ruscita(x) U_b_Ruscita = x
STATIC SWORD U_i_Ton_rf = 0;

/* You provide these functions. */
PROTO(BOOL Read_U_b_Yrf(void);)
PROTO(void Write_U_b_Yrf(BOOL v);)



/* Call this function once per PLC cycle. You are responsible for calling
   it at the interval that you specified in the MCU configuration when you
   generated this code. */
void PlcCycle(void)
{
    Write_I_b_mcr(1);
    
    /* start rung 1 */
    Write_I_b_rung_top(Read_I_b_mcr());
    
    /* start series [ */
    if(!Read_U_b_Xnew()) {
        Write_I_b_rung_top(0);
    }
    
    Write_I_b_scratch(Read_I_b_rung_top());
    if(!Read_I_b_rung_top()) {
        if(Read_I_b_oneShot_0000()) {
            Write_I_b_rung_top(1);
        }
    } else {
        Write_I_b_rung_top(0);
    }
    Write_I_b_oneShot_0000(Read_I_b_scratch());
    
    /* start parallel [ */
    Write_I_b_parOut_0000(0);
    Write_I_b_parThis_0000(Read_I_b_rung_top());
    if(Read_I_b_parThis_0000()) {
        Write_U_b_Rnew(1);
    }
    
    if(Read_I_b_parThis_0000()) {
        Write_I_b_parOut_0000(1);
    }
    Write_I_b_parThis_0000(Read_I_b_rung_top());
    Write_U_b_Rdue(Read_I_b_parThis_0000());
    
    if(Read_I_b_parThis_0000()) {
        Write_I_b_parOut_0000(1);
    }
    Write_I_b_rung_top(Read_I_b_parOut_0000());
    /* ] finish parallel */
    /* ] finish series */
    
    /* start rung 2 */
    Write_I_b_rung_top(Read_I_b_mcr());
    
    /* start series [ */
    if(!Read_U_b_Rnew()) {
        Write_I_b_rung_top(0);
    }
    
    if(Read_I_b_rung_top()) {
        if(U_i_Tdel < 9) {
            U_i_Tdel++;
            Write_I_b_rung_top(0);
        }
    } else {
        U_i_Tdel = 0;
    }
    
    Write_U_b_Rout(Read_I_b_rung_top());
    
    /* ] finish series */
    
    /* start rung 3 */
    Write_I_b_rung_top(Read_I_b_mcr());
    
    /* start series [ */
    if(!Read_U_b_Rout()) {
        Write_I_b_rung_top(0);
    }
    
    if(Read_I_b_rung_top()) {
        if(U_i_Tnew < 499) {
            U_i_Tnew++;
            Write_I_b_rung_top(0);
        }
    } else {
        U_i_Tnew = 0;
    }
    
    if(Read_I_b_rung_top()) {
        Write_U_b_Rnew(0);
    }
    
    /* ] finish series */
    
    /* start rung 4 */
    Write_I_b_rung_top(Read_I_b_mcr());
    
    /* start series [ */
    if(!Read_U_b_Rdue()) {
        Write_I_b_rung_top(0);
    }
    
    if(!Read_U_b_Rout()) {
        Write_I_b_rung_top(0);
    }
    
    if(Read_I_b_rung_top()) {
        Write_U_b_Ruscita(1);
    }
    
    /* ] finish series */
    
    /* start rung 5 */
    Write_I_b_rung_top(Read_I_b_mcr());
    
    /* start series [ */
    if(!Read_U_b_Ruscita()) {
        Write_I_b_rung_top(0);
    }
    
    if(Read_I_b_rung_top()) {
        if(U_i_Ton_rf < 49) {
            U_i_Ton_rf++;
            Write_I_b_rung_top(0);
        }
    } else {
        U_i_Ton_rf = 0;
    }
    
    if(Read_I_b_rung_top()) {
        Write_U_b_Ruscita(0);
    }
    
    /* ] finish series */
    
    /* start rung 6 */
    Write_I_b_rung_top(Read_I_b_mcr());
    
    /* start series [ */
    if(!Read_U_b_Ruscita()) {
        Write_I_b_rung_top(0);
    }
    
    Write_U_b_Yrf(Read_I_b_rung_top());
    
    /* ] finish series */
}

Certo! in verità per conversione in C intendevo ( :astonished:) la trasformazione in linguaggio IDE-compatibile.
Il problema l'avevo posto tempo fa ma poiché erà più elettronico che Arduinico avevo rinunciato, ora su suggerimento di una persona su un forum di elettronica, mi sono trovato questo codice.
Ho un sensore rotativo per antifurto, NC, collegato ad una tapparella (in realtà sono 7 le tapparelle). Non mi perdo nelle ragioni e spiego cosa devo ottenere:
1 - il primo impulso NA deve essere ignorato
2 - il secondo anche, ma se dopo questo passano 10 secondi senza che arrivi il terzo impulso il "contatore" si deve azzerare, quindi il successivo impulso deve essere considerato come se fosse il primo.
3 - se invece il terzo impulso arriva prima che trascorrano dieci secondi mi deve attivare un pin per 1 secondo (in questo modo piloto il tx radio per la centralina)
4 - subito dopo il terzo impulso (max 1 secondo) il circuito si deve resettare automaticamente.

Chi mi ha dato questo codice mi ha detto che faceva queste funzioni, se così fosse risolverei il mio problema con un micro in configurazione minima ed un piccolo circuito (già pronto) per filtrare gli impulsi spuri in ingresso ed un altro (già pronto) per pilotare il tx tramite il pin del micro (che a questo punto potrebbe essere un ATtiny per ridurre i consumi), oltre ovviamente ad un 78L05 o anche un circuito R-DZ-C per poter alimentare il micro a 5V partendo dai 12V della batteria del tx. Spero di essere stato chiaro e che mi possiate aiutare.

menniti:
Certo! in verità per conversione in C intendevo ( :astonished:) la trasformazione in linguaggio IDE-compatibile.

Il servizio conversione in wiring è chiuso fino a dopo la fine del mondo :grin:

Ho un sensore rotativo per antifurto, NC, collegato ad una tapparella (in realtà sono 7 le tapparelle). Non mi perdo nelle ragioni e spiego cosa devo ottenere:
1 - il primo impulso NA deve essere ignorato
2 - il secondo anche, ma se dopo questo passano 10 secondi senza che arrivi il terzo impulso il "contatore" si deve azzerare, quindi il successivo impulso deve essere considerato come se fosse il primo.
3 - se invece il terzo impulso arriva prima che trascorrano dieci secondi mi deve attivare un pin per 1 secondo (in questo modo piloto il tx radio per la centralina)
4 - subito dopo il terzo impulso (max 1 secondo) il circuito si deve resettare automaticamente.

Dove sarebbe mai il problema ?
Basta che leggi costantemente lo stato dei pin a cui sono collegati i 7 sensori e ogni volta che uno cambia di stato tramite la millis() attendi almeno 100ms prima di considerare nuovi cambi di stato, solo per quel pin, in pratica fai il debouncing a software, dopo di che, sempre tramite la millis(), ti crei il timeout, uno per ogni sensore, e conti gli impulsi che arrivano prendendo le opportune decisioni.

p.s.
Adesso non mi ci mandare, ma per questo genere di problematiche normalmente si usano le piccole mcu low cost, p.e. un 12F675 che costa meno di 1 Euro, delegando a loro tutto il compito di debouncing e decodifica degli stati.
Colleghi un 12F675 ad ogni sensore tapparella e ad Arduino mandi solo l'eventuale segnale d'allarme.

astrobeed:

menniti:
Certo! in verità per conversione in C intendevo ( :astonished:) la trasformazione in linguaggio IDE-compatibile.

Il servizio conversione in wiring è chiuso fino a dopo la fine del mondo :grin:

Ma come, tutti dicono ogni giorno "è arrivata la fine del mondo!" e tu mi rinvii a data da destinarsi? XD

Ho un sensore rotativo per antifurto, NC, collegato ad una tapparella (in realtà sono 7 le tapparelle). Non mi perdo nelle ragioni e spiego cosa devo ottenere:
1 - il primo impulso NA deve essere ignorato
2 - il secondo anche, ma se dopo questo passano 10 secondi senza che arrivi il terzo impulso il "contatore" si deve azzerare, quindi il successivo impulso deve essere considerato come se fosse il primo.
3 - se invece il terzo impulso arriva prima che trascorrano dieci secondi mi deve attivare un pin per 1 secondo (in questo modo piloto il tx radio per la centralina)
4 - subito dopo il terzo impulso (max 1 secondo) il circuito si deve resettare automaticamente.

Dove sarebbe mai il problema ?
Basta che leggi costantemente lo stato dei pin a cui sono collegati i 7 sensori e ogni volta che uno cambia di stato tramite la millis() attendi almeno 100ms prima di considerare nuovi cambi di stato, solo per quel pin, in pratica fai il debouncing a software, dopo di che, sempre tramite la millis(), ti crei il timeout, uno per ogni sensore, e conti gli impulsi che arrivano prendendo le opportune decisioni.
[/quote]
In realtà non devo usare Arduino per controllare tutto, ho già una bella centralina wireless che va una meraviglia, voglio proprio creare sette piccoli circuiti locali, per evitare i falsi allarmi che mi stanno facendo perire di crepacuore, per colpa di piccoli movimenti delle tapparelle, infatti ora mi metterò a cercare di scrivere il codice, chiederò poi aiuto per eventuali difficoltà

p.s.
Adesso non mi ci mandare, ma per questo genere di problematiche normalmente si usano le piccole mcu low cost, p.e. un 12F675 che costa meno di 1 Euro, delegando a loro tutto il compito di debouncing e decodifica degli stati.
Colleghi un 12F675 ad ogni sensore tapparella e ad Arduino mandi solo l'eventuale segnale d'allarme.

Non mi permetterei mai, nemmeno per scherzo! Anzi sappi che nella terza versione della guida su bootloader e sketch, che pubblicherò a brevissimo, ti ho ringraziato pubblicamente per l'aiuto che mi hai dato col generatore di sequenze di bit :wink:
Ciò detto non voglio allargare i miei "orizzonti" ai pic, ho già il mio bel daffare con l'ATmega328, alla fine, pure che spendo 5-6 euro a circuito non mi ridurrò in miseria e resterò nel mio standard. Invece come dicevo, una volta che lo schema funziona potrei comprare gli ATtiny che costano qualcosa in meno e visto l'uso che devo farne, andrebbero benissimo.
Grazie comunque della consulenza XD

Allora, ho seguito i vostri consigli, perso un'intero pomeriggio :blush:, ma alla fine ce l'ho fatta:
Questo codice legge gli impulsi del sensore, solo se ne invia almeno 5 attiva il tx e quindi l'allarme; se tra due successivi impulsi passano circa 10 secondi, lo interpreto come falso allarme e resetto il conteggio; poichè a volte il sensore resta in posizione "aperta" (è un NC) ho dovuto considerare anche questo e fare un conteggio a parte.

/*
 Gestione dei sensori per tapparelle dell'impianto di Antifurto 
 */

int sensore=2; //tra il pin 2 e massa collego il sensore con pull-up 10k
int valueSensore=0;
int preallarme=10; //opzionale, mi serve per controllare se funziona il sensore
int contatore=0; //contaimpulsi, dopo x impulsi attiva il TX
int counthigh=0; //contatore nel caso in cui il sensore resti attivo
long ritardo=0; //contatore della distanza tra due impulsi
int reset=7; //opzionale, serve per visualizzare l'attivazione del reset
int allarme=13; // uscita per pilotare il TX
int i=0;

void setup() {                
  pinMode(sensore, INPUT);
  pinMode(preallarme, OUTPUT); 
  pinMode(allarme, OUTPUT);  
  pinMode(reset, OUTPUT);
}

void loop() {
  valueSensore=digitalRead(sensore); //leggo lo stato del sensore
  if (valueSensore==HIGH) // se il sensore (NC) è su HIGH significa che è attivo
  {
    digitalWrite(preallarme,HIGH); //avviso sensore aperto
    delay(300); //ritardo antirimbalzo
    valueSensore=digitalRead(sensore); //rileggo lo stato del sensore
    if (valueSensore==LOW) // mi serve perché a volte il sensore rotativo resta su NA
    {
      digitalWrite(preallarme,LOW); // spengo il led di preallarme
      contatore++; //incremento il contatore degli impulsi
      ritardo=0; //azzero il conteggio del ritardo a partire dall'ultimo impulso del sensore
    }
    else
    {
      counthigh++; //incremento un altro contatore se il sensore resta bloccato su attivo
    }
  }
  if(contatore>=5) //questo valore è il numero degli impulsi che il sensore deve inviare per attivare il tx e far scattare l'allarme
  {
    digitalWrite(allarme,HIGH); //impulso positivo al TX
    delay(1000); //ritardo necessario al TX
    contatore=0; //azzero il contaimpulsi
    digitalWrite(allarme,LOW); // attivo il TX e faccio scattare l'allarme
  }
  ritardo++; //incremento il conteggio del ritardo, il sensore non ha inviato impulsi
  if (ritardo>=1000000 || counthigh>=30) // azzero tutto se passano circa 10 secondi dall'ultimo impulso o se per lo stesso tempo il sensore resta attivo
  {
    //resetto tutto
    contatore=0;
    counthigh=0;
    ritardo=0;
    i=0;
    for (int i=0;i<10;i++) //faccio lampeggiare il led del reset
    {
      digitalWrite(reset,HIGH);
      delay(50);
      digitalWrite(reset,LOW);
      delay(50);
    }
  } 
}

Certamente vi farà inorridire, ma è il mio primo vero programma, finora ho dedicato il mio poco tempo esclusivamente ad un circuito elettronico aggiuntivo per Arduino ed al tutorial su bootloader e sketch in stand alone (è quasi pronta la versone 3).
Vorrei migliorarlo su due problematiche:
1 – proprio all’inizio del loop leggo il sensore, se è HIGH dopo un po’ rifaccio la lettura per vedere se è andato su LOW o se è rimasto bloccato su HIGH (succede); tutto questo per contare gli impulsi HIGH-LOW; non c’è una funzione che mi permetta di verificare l’intero ciclo H-L senza fare due letture del pin?
2 – l’altro problema sono i contatori, ne ho 3: uno conta gli impulsi (v. punto 1) e mi sembra vada bene; un altro conta quanti cicli fa il loop se il sensore resta aperto (30 cicli, considerati i delay in gioco, sono circa 10 secondi); un altro conta quanti cicli fa il loop col sensore chiuso (1M di cicli sono circa 10 secondi).
Ecco il problema è tutto nel primo punto, se trovassi il modo di contare gli impulsi H-L senza fare due letture risolverei anche il problema di almeno un contatore; se poi trovassi un modo per contare il tempo tra due eventi risolverei anche l’altro contatore.
Ho provato la funzione millis() ma conta a partire dall’esecuzione del programma e non è azzerabile, o almeno non ci sono riuscito io.
Ho visto la funzione PulseIn ma non ho capito se può fare al caso mio, mi date qualche idea o secondo voi va bene anche così, ma ne dubito fortemente!

Beh, ho capito di aver scritto un codice perfetto :grin:
Un piccolo problema l'ho trovato:l'operazione di reset viene fatta ciclicamente e inutilmente, quindi l'ho vincolata alla verifica di almeno 1 impulso; invece per i problemi che ho segnalato continuo a non capirci nulla, proprio nessuna idea?
Vorrei inoltre un parere elettronico: lo schedino dovrebbe essere costituito da un ATmega (o ATtiny, devo verificare la fattibilità) in configurazione 8MHz:
1 - sapete dirmi come si fa questa configurazione? se ho capito bisogna attivare il clock interno, oltre a NON montare quarzo e C
2 - sarà costituito da chip, un rele reed a 5 o 12v, un paio di R, niente led. Viene alimentato dalla stessa batteria 12V (tipo telecomandi) del TX; posso stabilizzare la tensione con un circuito R-C-Zener5,1 o devo ricorrere ad un 78L05+2 C?
3 - secondo Voi quanto può consumare a riposo e quando pilota il rele?
Devo capire se posso continuare a garantire alla batteria del tx una durata decente o se mi conviene alimentare a parte lo schedino, ma vorrei evitarlo.
Dai, datemi qualche risposta :slight_smile:
Auguroni di buona Pasqua al Forum!

L'oscillatore interno viene attivato usando il fuse basso (lfuse). Andando qui:
http://www.engbedded.com/fusecalc/
puoi scegliere il micro e poi controllare il valore che valore mettere.
Devi scegliere internal oscillator 8 MHz 6/14 ck+65 ms e togliere lo spunto sul divisore 8x del clock (altrimenti ti farebbe andare il micro a 1 MHz).
Fatto questo avrai il valore da impostare tramite avrdude (oppure usando la mia tecnica di programmazione dei micro tramite Arduino UNO impostando il valore ottenuto per il fuse basso nei parametri all'interno del file boards.txt).

leo72:
L'oscillatore interno viene attivato usando il fuse basso (lfuse). Andando qui:
AVR® Fuse Calculator – The Engbedded Blog
puoi scegliere il micro e poi controllare il valore che valore mettere.
Devi scegliere internal oscillator 8 MHz 6/14 ck+65 ms e togliere lo spunto sul divisore 8x del clock (altrimenti ti farebbe andare il micro a 1 MHz).
Fatto questo avrai il valore da impostare tramite avrdude (oppure usando la mia tecnica di programmazione dei micro tramite Arduino UNO impostando il valore ottenuto per il fuse basso nei parametri all'interno del file boards.txt).

Scusa, vediamo se ho capito: sono andato sul link, ho scelto ATMEGA328P, internal ecc. era già di default, ho tolto la spunta al divisore 8x e in basso mi esce: -U lfuse:w:0xe2:m -U hfuse:w:0xd9:m -U efuse:w:0xff:m
Quindi ora dovrei aprire board.txt, inserire nella scheda ATMEGA (quella che hai fatto tu) il valore 0xe2 nella riga atmega.bootloader.low_fuses= e quindi inviare lo sketch al chip (con la tua modalità).
Così il chip lavorerà a 8MHz e inoltre caricherà lo sketch.
E' giusto o sbaglio qualcosa? I valori di fuse high ed extended li devo lasciare inalterati anche se sono diversi?
Per fare questo invio inizialmente il chip deve avere il quarzo o già non serve?
Un'altra cosa: se poi decido di riportare il chip a 16MHz mi basta rimettere il valore originario 0xff?
Grazie leo, fatti i dovuti esperimenti trasferirò tutto su ATtiny, perché credo consumi molto meno dell'ATmega328.

Sì, la procedura è quella indicata da te.
Serve per la programmazione un quarzo esterno perché in QUESTO momento il tuo micro è impostato per usarlo, quindi avresti dei problemi senza.

OK, grazie, credo che per ripristinarlo a 16MHz mi basterà fare l'operazione opposta. Domani farò le prove, ora mi servirebbero un po' di dati elettronici, come ho chiesto prima (alle modifiche del code rinuncio, tanto va bene :)) chissà se Uwe o Astrobeed sono in giro... o qualcun altro esperto in elettronica.

Mi serve qualche chiarimento, non ho mai usato ATmega a 8MHz.
Ho seguito alla lettera le istruzioni di leo, ed ho inviato il mio sketch ad un chip preconfigurando la breadboard col fuse per 8MHz. Lo sketch è andato regolarmente. Ma due cose non mi tornano:
1 - Lo sketch è stato eseguito regolarmente sulla bread ma ancora non avevo tolto il quarzo e i due C.
2 - Quando ho levato il quarzo e i due C (e dopo per prova anche la R da 10K sul reset), alimentando nuovamente non dà segni di vita.
3 - Rimontando quarzo e C il circuito funziona.
Allora significa che il chip ha ricevuto lo sketch ma non le impostazioni per levorare col clock interno a 8MHz.
Cosa ho sbagliato?
HELP!!! :astonished:

Aspetta un attimo.
Tu hai programmato un Atmega esterno, giusto?
Quindi hai modificato il file boards.txt. Nonostate questo, il micro sembra usare ancora il quarzo esterno, giusto?

Riguardati questo articolo:

sostituendo per l'lfuse il valore di 0xe2

Ciao leo, grazie.
Il tuo tutorial lo conosco a memoria, se non altro perché ci sto lavorando contemporaneamente sul mio.
L'operazione va sempre a buon fine, anche mettendo il valore 0xe2 come low_fuses.
Purtroppo (prova col blink) il chip continua a funzionare su una bread con quarzo ma non va su quella senza, ho fatto un milione di prove!
Ora, leggendo sul forum ho visto che è scritto che il chip deve avere un bootloader a 8MHz, ma la tua tecnica non mette nel chip il solo sketch "eliminando" il bootloader? Almeno io ho verificato che quando invio lo sketch in questa modalità, se poi monto il chip su Arduino non lo riconoscepiù, quindi ho dedotto.... e sta benissimo così! Ma allora perché nonostante il fuse non va?

Uhm... la tua è una supposizione logica.
Sinceramente non ho fatto molte prove perché il risultato era quello che volevo, ovvero avere un Arduino UNO capace di programmare chip Atmega standalone. Cmq il bootloader NON influisce sulle impostazioni del clock, quelle sono regolate unicamente dai fuse. Quindi che il micro abbia il bootloader o meno, all'atto pratico dell'esecuzione di un programma non c'è nessuna differenza.

Bisognerebbe inoltre capire come viene creato il file .hex da uploadare. Siccome il bootloader risiede nell'ultima porzione di memoria, se il file .hex non è più grande di tot_memoria-dim_bootloader in teoria il bootloader non dovrebbe venir sovrascritto. Quindi, una volta scritto, se non lo sovrascrivi, il bootloader rimane.

Va bene, ma questo ora è un problema relativo. Con la tua tecnica io creo i chip in stand alone e funzionano, com'è che cambiando il valore del l_fuse non succede nulla? Forse anche gli altri due fuses? ma tu hai mai provato a far funzionare un chip a 8MHz? non potresti scovare l'inghippo?
Il mio problema in realtà e che devo prima provare lo schedino "sul campo", poi devo realizzarne 7, e certamente userò ATtiny (col tuo tutorial naturalmente ;)), ma devo essere sicuro che circuito+software funzionino come si deve e che i consumi siano bassissimi, altrimenti rischio di spendere un sacco di soldini e non risolvere nulla. Puoi aiutarmi in qualche modo?

Posso provare, dammi una decina di minuti di tempo.

Anche 15, io intanto ti faccio il caffè XD Grazie!

Ti confermo che il chip, tolto il quarzo dopo la programmazione, non va.
Ho modificato il file boards.txt mettendo l'lfuse a 0xe2 ed il clock a 8 MHz, poi ho caricato lo sketch Blink e pareva funzionare correttamente ma, tolto il quarzo esterno, non è ripartito.

Osservando il lampeggio del LED, noto che la velocità del flash è doppia, segno che internamente i timing sono stati impostati correttamente per lavorare a 8 MHz ma che usa sempre il clock esterno da 16 MHz, quindi dimezzando il tempo del delay.

Cerco di fare un altro paio di prove...