accesso a più elementi di un array

salve!

un dubbio, avendo un array del tipo:
int numeri[] = {1, 2, 3, 4, 5, 6, 7};

vorrei usarlo per accendere contemporaneamente, ad esempio, 3 led

quindi:

digitalWrite (numeri[2], HIGH);
digitalWrite (numeri[3], HIGH);
digitalWrite (numeri[5], HIGH);

ma mi domandavo, non c'è un modo più immediato per avere accesso a più valori dell array?

mi immaginavo una cosa del tipo:

digitalWrite (numeri[2,3,4], HIGH);

Se gli elementi che ti interessano sono consecutivi, o comunque calcolabili con una formula matematica, puoi usare un ciclo for, altrimenti devi richiamare un elemento alla volta.

riesco a usare il for solo con elementi consecutivi ma io voglio accenderne di più contemporaneamente

credo che ci sia un modo per usare più elementi in poche righe

P.S: il mio è un dubbio unicamente logico non è che mi scoccio a scrivere due righe in più

Ripeto che l'unica cosa che puoi fare è tipo:

for (byte i = 2; i <= 4; i++) {
  digitalWrite (numeri[i], HIGH);
}

Non c'è altro modo.

ok grazie!

per semplificarmi complicarmi la vita mi stavo costruendo una mini libreria, giusto per capire un po come funziona, usando la guida sul forum arduino e altre. Facendo dei micro test funziona però passando a cose più complesse non riesco a usarla.

si basa su questo codice di controllo del 74HC595, per adesso tutte le funzioni per scrivere i numeri non sono complete visto che comunque non riesco a usare le classi

//74HC595
const int latchPin = 8;
const int clockPin = 12;
const int dataPin = 11;
int bitToSet = ;  //here



void setup() {
  
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  Serial.begin(9600);
  
}

void loop() {
registerWrite(bitToSet, HIGH);
}



void registerWrite(int whichPin, int whichState) {
  byte bitsToSend = 0;
  digitalWrite(latchPin, LOW);
  bitWrite(bitsToSend, whichPin, whichState);
  shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);
  digitalWrite(latchPin, HIGH);

}

il mio file .h

#ifndef Test_h
#define Test_h

#include "Arduino.h"

class Test {
  public:
    test(int a);
    latchPin(const int latchPin);
    clockPin(const int clockPin);
    dataPin(const int dataPin);

    void one();
    void two();
    void three();
    void four();
    void five();
    void six();
    void seven();
    void eight();
    void nine();
    void zero();
  private:
    int b;
    void registerWrite(int whichPin, int whichState);
};

#endif

il .cpp

#include "Arduino.h"
#include "Test.h"

Test::test(int a) {
  b = a;
}

Test::latchPin(const int latchPin) {
  pinMode(latchPin, OUTPUT);
}

Test::clockPin(const int clockPin) {
  pinMode(clockPin, OUTPUT);
}

Test::dataPin(const int dataPin) {
  pinMode(dataPin, OUTPUT);
}


void Test::one() {
  registerWrite(b, HIGH);
}

void Test::two() {
  registerWrite(b + 8, HIGH);
}

void Test::three() {
  registerWrite(b + 1, HIGH);
}

void Test::four() {
  registerWrite(b + 2, HIGH);
}

void Test::five() {
  registerWrite(b + 3, HIGH);
}

void Test::six() {
  registerWrite(b + 4, HIGH);
}

void Test::seven() {
  registerWrite(b + 5, HIGH);
}

void Test::eight() {
  registerWrite(b + 6, HIGH);
}

void Test::nine() {
  registerWrite(b - 1, HIGH);
}

void Test::zero() {
  registerWrite(b - 2, HIGH);
}

void Test::registerWrite(int whichPin, int whichState) {
  byte bitsToSend = 0;
  digitalWrite(latchPin, LOW);
  bitWrite(bitsToSend, whichPin, whichState);
  shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);
  digitalWrite(latchPin, HIGH);
}

negli allegati ho messo la libreria se qualcuno vuole provarci

keywords.txt (163 Bytes)

Test.cpp (1.02 KB)

Test.h (452 Bytes)

Francamente non capisco bene cosa vuoi fare. Cosa rappresenta l'attributo b?

Francamente... neppure io :slight_smile:

Cosa c'entra il 74HC595, con la domanda iniziale ?
Risposta a domanda iniziale: no, non puoi accedere a più elementi contemporaneamente.
Al massimo potresti usare i registri dei pin per attivare/disattivare i singoli bit quindi i singoli pin con una istruzione ma... i pin devono essere nello stesso "banco" e quindi registro. Inoltre perdi la compatibilità dei pin Arduino, devi usare i numeri di pin reali della MCU.
Il 74H anche lui ha un registro interno, quindi scrivere su di lui è paragonabile allo scrivere nel registro dei pin di una MCU. Accedi ai bit. Ma con i problemi di cui sopra se su MCU.
Nel caso poi di quella libreria... ma dov'e' la contemporaneità ?? Usa la funzione registerWrite() che viene chiamata enne volte, una per ogni bit, quindi NON c'e' contemporaneità, peggio di fare enne digitalWrite !!

Con la domanda iniziale non c entra. Sul fatto che alla fine il registerwrite(); è peggio dell digitalwrite(); ok, oltretutto non mi permette di usare bene il delay();

L obiettivo sarebbe avere una libreria che con un comando del tipo write(1,2,3,4; HIGH) porta alti i pin 1-4 del 74h

Quello che vuoi fare tu si può fare con delle bitmask e la manipolazione dei singoli bit, ma credo che sia una cosa un po' avanzata per il tuo attuale livello di conoscenze.

Inizia a fare una libreria con una funzione che prende la cifra da accendere come argomento, che internamente usa degli array di 0 e 1 (o true/false) per mappare ogni cifra ai segmenti da accendere. È cosa sicuramente utile e didattica, soprattutto quando passi a due cifre.

... forse la mia e' un'idea stupida (tieni presente che non sono un programmatore, quindi forse sto dicendo una cavolata) ... ma non si potrebbe creare una funzione a cui passare una variabile, e poi usare il binario del valore di questa variabile per accenderci e spegnerci le rispettive uscite ?

Cerco di spiegare cosa intendo ... creare per prima cosa una funzione a cui poter passare una variabile (diciamo di tipo byte per semplicita', cosi ci si possono pilotare 8 uscite), come ad esempio "int attiva(uscite)", e che contenga le istruzioni per trasformare il valore di "uscite" in binario (se non ricordo male si usa bitread, giusto ? ), ed usarli per accendere e spegnere le uscite corrispondenti (magari con un ciclo for del tipo "for A=0, A=7, A++", in cui il puntatore del for selezioni sia il bit che l'uscita, con dentro un'if tipo "se bitread(uscite, A) = 1 digitalWrite (uscita[A], High) else digitalWrite (uscita[A], LOW)" ... poi, dare ad "uscite" il valore corrispondente alla combinazione binaria delle uscite che si vogliono accese e spente, e passarla alla funzione, che si dovrebbe occupare di questa parte ...

... oppure dite che il caldo mi ha fuso il cervello ? ... :smiley:

È quello che ho appena detto :D.

SukkoPera:
Quello che vuoi fare tu si può fare con delle bitmask e la manipolazione dei singoli bit, ma credo che sia una cosa un po' avanzata per il tuo attuale livello di conoscenze.

Inizia a fare una libreria con una funzione che prende la cifra da accendere come argomento, che internamente usa degli array di 0 e 1 (o true/false) per mappare ogni cifra ai segmenti da accendere. È cosa sicuramente utile e didattica, soprattutto quando passi a due cifre.

esatto, il problema attuale è il mio livello di conoscenza, infatti non so cosa siano le bitmask. comunque l obiettivo è puramente di imparare, pensavo di riuscire a fare una libreria base direttamente per il 74H ma parto un pò più dal basso che è meglio

Esatto, bisogna procedere per gradi. Cerca prima di capire le peculiarità degli array e poi vedrai che è molto semplice.

PS: 74 è la serie intera di componenti, dovresti dire "per il 595" ;).

SukkoPera:
È quello che ho appena detto :D.

Dal che si evince ancor di piu che non sono un programmatore, dato che avevo capito una cosa diversa :smiley:

alla fine ho optato per questo:

//74HC595
const int latchPin = 8;
const int clockPin = 12;
const int dataPin = 11;

//others
int buttonPin = 2;
boolean state1;
boolean state2;
boolean pressed;
int led = 7; //led di debugg
int password = 8;
int input;

//segmenti
byte a = B100000;
byte b = B10000;
byte c = B1000;
byte d = B100;
byte e = B10;
byte f = B1000000;
byte g = B10000000;
byte dot; //not in use

//numeri
byte n1 = b + c;
byte n2 = a + b + d + e + g;
byte n3 = a + b + d + c + g;
byte n4 = b + c + f + g;
byte n5 = a + f + d + c + g;
byte n6 = a + c + d + e + f + g;
byte n7 = a + b + c;
byte n8 = a + b + c + d + e + f + g;
byte n9 = a + b + c + d + f + g;
byte n0 = B0;


void setup() {

  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(led, OUTPUT);
  registerWrite(n0); //cleaning the display

}

void loop() {

  //lettura pulsante con debugg
  state1 = !digitalRead(buttonPin);
  delayMicroseconds(200);
  state2 = !digitalRead(buttonPin);

  if (state1 == 1 && state2 == 1) {
    pressed = true;
  } else {
    pressed = false;
  }

  if (pressed == 1) {

    countdown();

    input = Serial.read() - 48; //it works only in ASCII :(

    if (input == password) {
      Serial.println("YOU SAVED THE WORLD");
      delay(3000);
    } else {
      Serial.println("WE ARE DEATH");
      delay(3000);
    }
  }
}

void countdown() {
  registerWrite(n9);
  delay(1000);
  registerWrite(n8);
  delay(1000);
  registerWrite(n7);
  delay(1000);
  registerWrite(n6);
  delay(1000);
  registerWrite(n5);
  delay(1000);
  registerWrite(n4);
  delay(1000);
  registerWrite(n3);
  delay(1000);
  registerWrite(n2);
  delay(1000);
  registerWrite(n1);
  delay(1000);
  registerWrite(n0);
  delay(1000);
}


void registerWrite(int bitsToSend) {
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);
  digitalWrite(latchPin, HIGH);
}

che praticamente lo potrei trasformare in una libreria, almeno credo, l unica cosa per cui mi viene il dubbio è quella funzione registerWrite, una funzione di una libreria può richiamare una funzione all interno della stessa libreria?

tipo lcd.n8();

può essere all interno della libreria una cosa come questa:

void n8 (){
registerWrite(n8);
}

oppure devo scrivere:

void n8(){

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, n8);
digitalWrite(latchPin, HIGH);
}

Beh, in verità non è male, è più o meno quello che ti suggerivamo sopra. Ora, se invece di avere 10 variabili diverse n0... n9, le mettessi in un array...

registerWrite() non è una funzione di libreria, è definita proprio lì nel tuo codice. Metti anche quella dentro alla libreria senza alcun dubbio! Anche se potresti farne a meno, se ci pensi un po' ;).

le mettessi in un array...

ci volevo provare ma con gli array sono abbastanza negato ad essere sincero

per registerWrite so che è definita nel mio codice, avevo il dubbio se una funzione dentro una libreria può chiamare una funzione dentro la stessa libreria (non so se sono chiaro) ma immagino di si
per farne a meno della funzione l unica cosa è che la metterei direttamente dentro i singoli numeri tipo il secondo esempio che ho scritto:

void n8(){

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, n8);
digitalWrite(latchPin, HIGH);
}

altro purtroppo non mi viene

Non c'è nessun problema a richiamare funzioni, ci mancherebbe. Ma pensa all'array, ormai sei a un passo dalla soluzione ottima!

Un suggerimento, anche se mi sembra così evidente da come l'hai scritto!

byte n1 = b + c;
byte n2 = a + b + d + e + g;
...

Non ti sembra assolutamente naturale farlo diventare:

byte n[10];
n[0] = 0;
n[1] = b + c;
n[2] = a + b + d + e + g;
...

Per semplificare le cose, facciamo dichiarazione e definizione in un colpo solo:

byte n[] = {
  0,
  b + c,
  a + b + d + e + g,
 ...
};

Già che ci siamo ti consiglio di metterci const davanti, sia a questo che ad a, b, c, ecc...

Vediamo se capisci qual è il pro di fare in questo modo ;).