Scusate, mi dispiace riportare il post in prima fila, ma speravo in una risposta perchè non so come andare avanti. A volte quando si scrivono strafalcioni, ci vediamo bene di lasciare stare per evitare di dover spiegare argomenti non trattati per spiegare un concetto, magari semplice
Quello che cerco è di arrivare ad una soluzione piu o meno vicina a quello che vorrei realizzare e nel precedente post ho scritto quello che mi serve, quello che ho trovato, e se siamo sulla buona strada o meno. Vi prego, se ritenete non corrette le cose che ho scritto, basta solo saperlo, non serve spiegazioni almeno posso abbandonare quella strada e vedere una soluzione alternativa..ci conto e scusate se ho rianimato il mio posto ormai abbandonato da diversi giorni.
Saluti a tutti
Figurati ... il necroposting (riportare in vita threads defunti :P) c'e' solo quando i post sono ormai morti da almeno un paio di mesi o piu (e quindi non hanno piu un bell'aspetto ... no, aspetta, i post non si decompongono ... ah, va bene, comunque il senso si capiva :D), le settimane non contano ... se nessuno ti ha ancora rispostonon credo sia perche' non vogliono farlo (se cosi fosse te l'avrebbero detto), e' probabilmente solo perche' nessuno di quelli che hanno una risposta ha ancora letto il post (c'e' anche gente che non si collega per giorni) oppure perche' chi ha letto non sa cosa dirti a livello software (come me, che essendo un tecnico hardware, con la programmazione ci litigo ogni volta, e la maggior parte delle volte le prendo pure
:D)
Non ne sono sicuro, ma credo che shiftin legga un byte alla volta (sempre sotto forma di 8 bit, che quindi devi infilare in un'array, e poi gestire dopo l'acquisizione a livello di singoli bit) ... quanto alla lunghezza della catena, a livello hardware, a me fino a sei chip non ha mai dato particolari problemi, ma ho letto una volta in un'altro forum, non ricordo dove sara' stato un'anno fa', che catene piu lunghe davano problemi di interferenza o false letture, quindi magari e' meglio sprecare qualche pin in piu e fare piu catene da leggere con diversi banchi di ingresso, ad esempio 3 catene da 4 chip ... pero' non ho idea se questo possa incasinare poi il software ...
ciao
non conosco i 74hc165 io ho lavorato con i CD4021 quello che vai leggere seguono l'ordine di come sono collegati gli shiftin
digitalWrite(latchPinIN, HIGH); //set it to 1 to collect parallel data, wait
delayMicroseconds(50);
digitalWrite(latchPinIN, LOW); //set it to 0 to transmit data serially
//while the shift register is in serial mode
//collect each shift register into a byte
//the register attached to the chip comes in first
switchVar2 = shiftIn(dataPinIN, clockPinIN);//1_5
switchVar1 = shiftIn(dataPinIN, clockPinIN);//6_10
immagina di osservare un treno:
1 vagone 1 byte 1 variabile
...
Grazie per le delucidazioni sul post, ma non volevo risultare insistente e antipatico.
Grazie per la dritta, in effetti non posso assolutamente rischiare di non ricevere un comando perchè si tratta dei ritorni di stato di tutte le apparecchiature elettriche di casa (stato serrande, prese, luci, caldaia ecc) comunque non sono di vitale importanza, sono solo gli stati visivi sulla situazione generale. Comunque nella vecchio sketch ho inserito una linea di comando inviata dal mio software che, se la ricezione è incomprensibile, richiama tutti gli stati e fino a quando non lo ha ricevuto, il comando di richiamo viene inviato in modo continuo. La dritta di utilizzare piu catene, impegnando magari 9 pin con 3 chip per catena, si ottiene 24x3=72 ingressi MOLTO INTERESSANTE
Cosa semplice, ma non mi è venuta in mente.
Sarà piu incasinata la cosa, ma pago volentieri un valido programmatore abilissimo con arduino solo se ho una base hardware valida.
Visto che sei un progettista hardware, cosa ne pensi del mio progetto labdomotic?
cerca sul web e vedi le mie interfacce labdomotic.
Comunque grazie, ho le idee piu chiare, anche se non assolutamente vero
Ho visto questo articolo molto interessante con i CD4021 per espandere il numero degli ingressi:http://www.arduino.cc/en/Tutorial/ShiftIn
Ed è proprio quello che stavo cercando.
Ho visto anche uno sketch già pronto, potete aiutarmi a capirlo velocemente?
//define where your pins are
int latchPin = 8;
int dataPin = 9;
int clockPin = 7;
//Define variables to hold the data
//for shift register.
//starting with a non-zero numbers can help
//troubleshoot
byte switchVar1 = 72; //01001000
//define an array that corresponds to values for each
//of the shift register's pins
char note2sing[] = {
'C', 'd', 'e', 'f', 'g', 'a', 'b', 'c'};
void setup() {
//start serial
Serial.begin(9600);
//define pin modes
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, INPUT);
}
void loop() {
//Pulse the latch pin:
//set it to 1 to collect parallel data
digitalWrite(latchPin,1);
//set it to 1 to collect parallel data, wait
delayMicroseconds(20);
//set it to 0 to transmit data serially
digitalWrite(latchPin,0);
//while the shift register is in serial mode
//collect each shift register into a byte
//the register attached to the chip comes in first
switchVar1 = shiftIn(dataPin, clockPin);
//Print out the results.
//leading 0's at the top of the byte
//(7, 6, 5, etc) will be dropped before
//the first pin that has a high input
//reading
Serial.println(switchVar1, BIN);
//This for-loop steps through the byte
//bit by bit which holds the shift register data
//and if it was high (1) then it prints
//the corresponding location in the array
for (int n=0; n<=7; n++)
{
//so, when n is 3, it compares the bits
//in switchVar1 and the binary number 00001000
//which will only return true if there is a
//1 in that bit (ie that pin) from the shift
//register.
if (switchVar1 & (1 << n) ){
//print the value of the array location
Serial.println(note2sing[n]);
}
}
//white space
Serial.println("-------------------");
//delay so all these print satements can keep up.
delay(500);
}
//------------------------------------------------end main loop
////// ----------------------------------------shiftIn function
///// just needs the location of the data pin and the clock pin
///// it returns a byte with each bit in the byte corresponding
///// to a pin on the shift register. leftBit 7 = Pin 7 / Bit 0= Pin 0
byte shiftIn(int myDataPin, int myClockPin) {
int i;
int temp = 0;
int pinState;
byte myDataIn = 0;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, INPUT);
//we will be holding the clock pin high 8 times (0,..,7) at the
//end of each time through the for loop
//at the begining of each loop when we set the clock low, it will
//be doing the necessary low to high drop to cause the shift
//register's DataPin to change state based on the value
//of the next bit in its serial information flow.
//The register transmits the information about the pins from pin 7 to pin 0
//so that is why our function counts down
for (i=7; i>=0; i--)
{
digitalWrite(myClockPin, 0);
delayMicroseconds(0.2);
temp = digitalRead(myDataPin);
if (temp) {
pinState = 1;
//set the bit to 0 no matter what
myDataIn = myDataIn | (1 << i);
}
else {
//turn it off -- only necessary for debuging
//print statement since myDataIn starts as 0
pinState = 0;
}
//Debuging print statements
//Serial.print(pinState);
//Serial.print(" ");
//Serial.println (dataIn, BIN);
digitalWrite(myClockPin, 1);
}
//debuging print statements whitespace
//Serial.println();
//Serial.println(myDataIn, BIN);
return myDataIn;
}
Non intendo linea per linea, intendo capire cosa ricevo tramite la seriale. Purtroppo non ho quel componente in casa e devo aspettare la prossima settimana per fare test.
Per caso ricevo un flusso continuo di dati tramite seriale oppure viene inviato solo ad oogni cambio di stato?
Lo so che non c'è nel codice l' invio tramite seriale, viene suggerito tra i commenti.
es:
//Debuging print statements
//Serial.print(pinState);
//Serial.print(" ");
//Serial.println (dataIn, BIN);
Se dovessi utilizzare altri tre pin per collegare una catena nuova di integrati 4021 per evitare di creare troppo paralleli su tre pin, il codice cambia drasticamente?
edstarink:
... cosa ricevo tramite la seriale. ...
A quanto ho capito, nulla ... la seriale non la usi per leggere gli shift register, ma per mandare al monitor seriale il risultato ... gli shift vengono letti dal pin digitale a cui e' collegata la loro uscita (dataPin, in quel caso) ...
Esattamente, Intendevo quello...il risultato finale.
Purtroppo per me è fondamentale avere tramite seriale lo stato degli ingressi perchè arduino e gli shift register sono usati come "lettore" e non come elaboratore che legge, interpreta e condiziona le uscite in relazione a come saranno scritti gli eventi al suo interno. Arduino tutto quello che fa me lo deve inviare tramite seriale, che sia una sensore o più sensori oppure gli stato degli ingressi.
In quello sketch, non vedo un comando per l' invio tramite seriale serial.print, ma basta solo scrivere, quello che non ho ancora capito, è come interpretare quegli ingressi o meglio, come dovrebbero essere inviati tramite seriale per avere il loro stato naturale. Non trovo molto sul web come accoppiata tra arduino e i cd4021.
Siccome chiedo a voi che siete esperti, se dovete avere lo stato di almeno 80-90 ingressi, per avere su un monitor seriale il loro stato, come scrivereste il codice da inviare da arduino ad un pc per esempio?
Mi sta mandando fuori di testa questo aspetto.
Intendo un comando che non impegna la porta com naturalmente.
scrivi su seriale il contenuto delle variabili
serial.println(var1, BIN)
serial.println(var2, BIN)
....
Si, quello lo sapevo, grazie comunque, quello che volevo invece sapere è cosa mi arriva al pc tramite seriale. Se si tratta di avere lo stato dei pin di arduino è semplice, posso leggere lo stato di tutti i pin, metterli dentro un' array e inviare il contenuto del' array formato dai caratteri, ma con gli shift in non saprei...
Uhm, credo non sia molto diverso, alla fine ... se leggi i pin, li metti in un'array ed invii il contenuto come carattere esadecimale, allora con lo shiftin dovresti poter fare lo stesso, la differenza e' che lo shiftin ti mette nell'array 8 bit alla volta invece che uno alla volta come per i pin singoli (cioe' legge tutti gli 8 bit di uno shift register insieme e te li mette gia lui nell'array, invece di doverlo fare tu un bit alla volta ... come poi usi l'array lo decidi tu dopo, quindi se vuoi puoi anche spedirlo come carattere, come facevi per i singoli pin)
Scusa il ritardo...credo di aver capito.
Mi rimane ancora una cosa poco chiara.
L' array è molto grande da inviare via seriale, considera che ogni cella del' array contiene gli 8 bit di ogni integrato giusto? quindi se avessi un totale di 8 integrati l' array occupa 8 celle da 8bit ciascuna.
Inviare un' array cosi grande, considerando che non posso inviarlo in una sola volta, la soluzione è quella di inviare un serialLn di tutto l' array come nel' esempio sotto riportato:
A00100110%
B00000000%
C00100010%
D10010110%
E00100110%
F00100110%
G11000110%
H00110110%
Non mi piace moltissimo, troppo flusso sulla seriale
La mia idea è invece questa:
Utilizzerò 8 cd4021 e voglio occupare solamente 12 pin (con tre pin utilizzo 2 paralleli per avere maggiore sicurezza).
Facciamo un' esempio, se il primo integrato da 8 ingressi, subisce una variazione ad uno dei suoi ingressi, invia dentro un' array (ARRAY_A) gli 8 ingressi aggiornati e di conseguenza invia tramite seriale solo quelli. una stringa formata da 10 caratteri con una lettera iniziale per identificare da quale integrato proviene e una finale come verifica di integrità.
In questo modo ho la seriale quasi sempre libera e maggiore sicurezza che la stringa non abbia errori.
Cosa ne pensate, ha senso tutto questo?
edstarink:
... se il primo integrato da 8 ingressi, subisce una variazione ad uno dei suoi ingressi, invia dentro un' array (ARRAY_A) gli 8 ingressi aggiornati ...
No ... gli shift register non hanno un'uscita interrupt che ti dice che lo stato e' cambiato, ne tantomeno inviano dati se non vengono letti ... e' il tuo sketch che deve leggerli ciclicamente per estrarne i dati ... quando tu fai una lettura con shiftin, arduino invia i treni di impulsi e di clock corrispondenti sui relativi pin e legge lo stato del pin di ingresso, mettendo il valore nell'array, ma se non la fai tu la lettura, lo shift register non ti "invia" nulla, ne quando lo stato e' costante, ne quando cambia ... quindi nei cicli di lettura, il sistema e' comparare la lettura con quella memorizzata il ciclo prima, e spedire il dato solo se c'e' differenza ...
Si, intendevo nello sketch. se lettura attuale è differente da lettura, aggiorna la variabile lettura con quella attuale ed invia tramite seriale.
Converti in HEX i valori e ti ritroverai sulla seriale
FF, FF, FF, FF, FF, FF, FF, FF
scrivere A B C D È F G H è inutile visto che la sequenza è sempre la stessa
intendi convertire lo stato di tutti gli ingressi in formato esadecimale?
ottima soluzione, l' unica differenza rispetto al decimale è che ho un carattere di meno.
il "10" nel decimale corrisponde alla lettera "A" del codice esadecimale
il "255" corrisponde alle lettere "FF" del' esadecimale.
quindi, per un totale di 8 integrati collegati, dovrei ricevere una stringa simile a questa?
esadecimale= 20, 4D, 78, 45, 3, D, 5A, 6C
se fosse stato inviato un valore binario avrei avuto questo:
binario= 32, 77, 120, 69, 13, 90, 108
Diciamo che non vedo grosse differenze. Forse la difficoltà e riconvertire questi valori in modo che possa mettere dentro un' array i valori su cui posso lavorare.
Non voglio ricevere lo stato di tutti gli ingressi, voglio solo ricevere lo stato solo quando c' è una variazione. Avendo solamente pochi cambi di stato, visto che non ho alte frequenza di commutazione, se al 9 pin ho una variazione, devo ricevere solo lo stato del secondo integrato visto che la variazione è stata fatta solo su quello e da seriale ricevere solamente questo:
10000000
è possibile fare questo oppure è illogico?
Il mio Software è composto da tantissime variabili dove ad ogni variabile corrisponde lo stato degli ingressi ricevuti tramite seriale. Non ho usato un' array per questione di versatilità, è difficile da spiegare. Un' array in MMF2 non è condiviso con gli altri livelli del Software, mentre le variabili globali si quindi, ho dovuto creare una struttura come questa:
ARDUINO_INPUT_1=1
ARDUINO_INPUT_2=0
ARDUINO_INPUT_3=0
ARDUINO_INPUT_4=1
ARDUINO_INPUT_5=0
ARDUINO_INPUT_6=1
ARDUINO_INPUT_72=1
Mi risulta un po scomodo su una stringa ricevuta da seriale come questa:
20, 4D, 78, 45, 3, D, 5A, 6C
aggiornare lo stato delle mie variabili.
dovrei prendere i primi DUE caratteri (20) e aggiornare le prime otto variabili a seconda dello stato di come sono attualmente i primi ingressi.
se avessi ricevuto lo stato dei primi 8 ingressi in formato binario, sarebbe stato più semplice.
00101111
Basterebbe aggiornare le variabili globali del mio software in relazione alla disposizione degli "0" e "1"
Solo che una stringa come questa diventa ingestibile e poco sicura:
00101000, 11001101, 11000011, 01101001, 01110111, 00010010, 10111110, 11000000
La catena di shift register la devi comunque leggere tutta, ogni volta che fai una lettura, per sapere se il primo, l'ultimo, o uno o piu in qualsiasi posizione degli ingressi e' cambiato ... quindi non dovrebbe essere un problema spedirla tutta ad un PC (che e' comunque piu veloce di Arduino), perche' alla fine si tratterebbe di spedire otto coppie di caratteri ...
Scusa, perche' un'array non e' condiviso ? ... non li dichiari come globali ?
Purtroppo l' array è un' estensione non condivisa, solo le variabili globali possono essere lette da qualsiasi livello e considerata la quantità di livelli che ho creato, se non ho una situazione leggibile da qualsiasi livello, mi tocca lavorare su un file temporaneo condivisibile.
Comunque per me è meglio così, ho un debug molto più intuitivo e con le variabili globali posso fare la stessa cosa che si fa con un' array. L' array lo uso per l' archiviazione di parametri presi dalle variabili globali mentre uso l' array 3d per il salvataggio su file.
Allora se mi dici che spedire tutto lo stato di tutti gli ingressi non comporta nulla, almeno consigliami il formato
decimale, binario, hex? quale tra questi è più indicato?
Peccato che non ho gli integrati, domani faccio un' ardine su RS così posso provare di persona tra le due versioni ttl e cmos.
Posso contare su di voi per adattare quello che ho trovato con quello che devo realmente realizzare?
Scusate, ci sono stati aggiornamenti e un solo problema finale.
Ho trovato un' amico che mi ha aiutato a scrivere un codice che gestisce 12 74HC165
Avevo un probelma che sono riuscito a risolvere grazie ad un vecchio post e grazie a Etemenanki per aver trovato la soluzione.
Venivano inviati via seriale moltissimi comandi anche quando non accadeva nessuna variazione di ingresso. La resistenza da 1k tra il pin 9 e la massa e una tra il pin 10 e la massa hanno risolto il problema.
PROBLEMA PIU GRANDE, INVERSIONE VALORI...DA COSA DIPENDE?
Ho collegato 4 74hc165 per un totale di 32 ingressi ma quando vado a commutare il pin 6 del primo chip, non viene inviato niente tramite seriale. Il circuito elettrico va bene anche perchè l' ho realizzato su tre modelli:
B.B piccola, B.B grande e millefori. Stesso problema.
se porto il positivo al pin 6 del secondo chip, cosa assurda, viene inviato tramite seriale lo stato di tutti gli ingressi del chip1, naturalmente in questo caso il valore binario dello stato del pin 6.
Sarebbe corretto se invece di indicare che la variazione fosse avvenuta dal chip 1. Io credo che il problema sia a livello di sketch, potete capire la natura del problema??
PREMESSA:
Se viene modificato uno degli ingressi del chip3, mi arriverà da seriale questo valore:
chip3=219 (219 è il valore binario degli ingressi di quel' integrato.
Questa cosa dovrebbe accadere anche con gli altri chip, ma se modifico il pin 6 del chip1 trovo questo:
NESSUN COMANDO INVIATO
Se modifico l' ingresso del pin 6 del chip 2 mi ritrovo questo
chip1-119 invece di (chip2-119)
Posto lo sketch, forse è li il problema anche perchè elettricamente è tutto corretto.
const int IN_PL = 9;
const int IN_Data=10;
const int IN_Clock=8;
const int NUM_CHIP=4;
int attuale[4]; // arrai per tenere le letture attuali
int lettura[4]; // array per tenere l'ultima lettura fatta.
void setup()
{
pinMode(IN_PL,OUTPUT);
pinMode(IN_Data,INPUT);
pinMode(IN_Clock,OUTPUT);
for(int i=0;i<NUM_CHIP;i++) {attuale[0]=0;lettura[0]=0;} // inizializzo gli array a 0
Serial.begin(9600);
}
void loop()
{
delay(50);
digitalWrite(IN_PL, LOW);
digitalWrite(IN_PL, HIGH);
for(int i=0;i<NUM_CHIP;i++) lettura[i]=shiftIn(IN_Data, IN_Clock, MSBFIRST ); // faccio tutte le letture
for(int i=0;i<NUM_CHIP;i++) // controllo se ci sono modificazioni
{
if(attuale[i]!=lettura[i])
{
attuale[i]=lettura[i];
Serial.print("chip-");
Serial.print(i);
Serial.print(" - ");
Serial.println (lettura[i]);
}
} // chiusura for
}
Forse ho scritto troppo mettendo la mia problematica alla fine
Vorrei solamente capire se lo sketch presenta errori perchè ho un comportamento anomalo.
Schema elettrico corretto realizzato su millefori con particolare attenzione.
ho diversi 74HC165 ma il pin 6 di tutti gli integrati, si comportano in modo errato.
pin6 del primo chip non invia nulla (come se fosse morto)
pin6 del secondo chip, invia lo stato degli 8 ingressi del primo.
Sembra quasi un problema di clock, come se qualcosa fosse sfalsato.
Sapete aiutarmi? sto perdendo giorni di lavoro senza risolvere questo problema. Posso affidarmi solo a voi
for(int i=0;i<NUM_CHIP;i++) lettura*=shiftIn(IN_Data, IN_Clock, MSBFIRST ); // faccio tutte le letture[/quote]*
premetto che non sono un esperto di C e la mia osservazione potrebbe essere errata, hai provato a scrivere con le parentesi il primo FOR
> for(int i=0;i<NUM_CHIP;i++)
> {
> lettura*=shiftIn(IN_Data, IN_Clock, MSBFIRST ); // faccio tutte le letture*
> }
> [/quote]