DIP Schalter zur Programmauswahl

Moin Also ich habe vor dem ws2812b (oder anderen Stripes oder Bauteilen) per DIPSchalter diverse Programme zuzuweisen

Im Beispiel ein Knightrider lauflicht für die WS2812

Nun die eigentliche Frage geht das einfacher als in meinem Beispiel (für dessen Sinnvolle und richtige Funktion ich natürlich nicht bürge ^^)

#include <Adafruit_NeoPixel.h>
#define PIN 10
Adafruit_NeoPixel strip = Adafruit_NeoPixel(8, PIN, NEO_GRB + NEO_KHZ800);
int wc = 0;
int t;

void setup()
//Dipschalter eingänge
{
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  pinMode(8, INPUT);
  pinMode(9, INPUT);

strip.begin();
strip.show();
}

void loop() {
  if (  digitalRead(2) == digitalRead(6) && digitalRead(3) == digitalRead(7) && digitalRead(4) == digitalRead(8) && digitalRead(5) == digitalRead(9)   ) //Schalterstellung für programm einlesen
   
  for (int i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, Wheel(wc));
    t = i - 1;
    if (t < 0) t = strip.numPixels() - 1;
    strip.setPixelColor(t, strip.Color( 0, 0, 0));
    strip.show();
    delay(50);
  }
  for (int i = strip.numPixels() - 1; i >= 0; i--) {
    strip.setPixelColor(i, Wheel(wc));
    t = i + 1;
    if (t >= strip.numPixels()) t = 0;
    strip.setPixelColor(t, strip.Color( 0, 0, 0));
    strip.show();
    delay(50);
  }
  wc++;
  if (wc > 255) wc = 0;
}

uint32_t Wheel(byte WheelPos) {
  if (WheelPos < 85) {
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
    WheelPos -= 170;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

Ich frage halt jedesmal die Stellung pro funktion ab . Das geht zwar aber bei 12 oder 13 Funktionen is das halt sehr viel Schreibarbeit .Grad bei 8 oder 16 Bit ^^

Geht das einfacher/kürzer.

Würde auch gern bei Dip bleiben und keine Drehschalter Potis oder irgendwelche Wiederstandsänderungsgeschichten benutzen .

LG und Danke im Vorraus .

Geht das einfacher/kürzer.

Vielleicht...

z.B. Wenn du alle DIPs auf einen 8Bit Port bekommst.
Dann könntest du auch noch im Flash eine Funktionszeiger Tabelle anlegen.

Damit reduziert sich das Abfragen der Schalter und ausführen der Funktion auf ca 2 Zeilen Code.

Der Trick ist es, den Wert der Schalterstellung in einer Variable unterzubringen.

uint8_t mode = 0;
mode = digitalRead(pin7) << 7 | digitalRead(pin6) << 6 /..../ | digitalRead(pin0) << 0;

switch(mode)
{
case 0:

break;
case 1:

break;
// ...
}

Oder man löst das über I2C und einen Portexpander.
Dann kann man Hexwerte zur Abfrage nutzen.
Wäre doch eine Alternative, oder?

sschultewolter:
Der Trick ist es, den Wert der Schalterstellung in einer Variable unterzubringen.

du meinst so ?

int DIPPin[] = {2, 3, 4, 5, 6, 7, 8, 9}; 
int Programm;

void setup()
{
 Serial.begin(2400);
 int i;
 for(i = 0; i<=7; i++){
 pinMode(DIPPin[i], INPUT);      
 digitalWrite(DIPPin[i], HIGH); 
 }
 Programm = Schalterstellung();
 delay(100);
}


void loop()
{

switch(Programm)
{
case 0:

break;
case 1:

break;
// ...
}

}


byte Schalterstellung()

{
 int i,j=0;
 
 
 for(i=0; i<=7; i++){
 j = (j << 1) | digitalRead(DIPPin[i]);   
 }
 return j; 
}

Hot System ja das wäre eine Alternative (musste erst Nachschauen was genau das ist ^^) ich behalte das mal als Plan B feste . Müsste die Teile noch bestellen .

const uint8_t dipCount = 8;
const uint8_t dip[dipCount] = {2, 3, 4, 5, 6, 7, 8};
uint8_t getMode(void)
{
	uint8_t retValue = 0;
	
	for(uint8_t ct = 0; ct < dipCount; ct++)
	{
		retValue |= digitalRead(dip[ct]);
	}
}

Wenn nur Schalter 1 gedrückt ist, ergibt dass den Wert 1.
Wird zusätzlich noch Schalter 7 gedrückt, so ist der Wert 127+1.

Schwesterstefan:
Hot System ja das wäre eine Alternative (musste erst Nachschauen was genau das ist ^^) ich behalte das mal als Plan B feste . Müsste die Teile noch bestellen .

Ja, ok. Ist wirklich nur ein Alternative zur obigen Lösung, aber recht effektiv, da man ja auch Ports am Arduino spart und bei einen 8Port Baustein PCF 8574 volle 8Bit (256 Eingänge) zur Verfügung hat.

Edit:
Keine Eingänge sondern Möglichkeiten.

sschultewolter:

const uint8_t dipCount = 8;

const uint8_t dip[dipCount] = {2, 3, 4, 5, 6, 7, 8};
uint8_t getMode(void)
{
uint8_t retValue = 0;

for(uint8_t ct = 0; ct < dipCount; ct++)
{
	retValue |= digitalRead(dip[ct]);
}

}




Wenn nur Schalter 1 gedrückt ist, ergibt dass den Wert 1.
Wird zusätzlich noch Schalter 7 gedrückt, so ist der Wert 127+1.
const uint8_t dip[dipCount] = {2, 3, 4, 5, 6, 7, 8, 9};
retValue |= digitalRead(dip[ct])<<ct;

????

Nachtrag:
Ich habe mal deins, sschultewolter, mit Code aus meiner Wühlkiste verschmolzen und komme dann auf:
(2 Dipschalter 4 Funktionen)

typedef void FUNC();
const uint8_t dipCount = 2;
const uint8_t dip[dipCount] = {2, 3};
const byte pointers = 1 << dipCount;
const FUNC* const PointerFeld[pointers] PROGMEM  = {f0,f1,f2,f3};


void setup() 
{
 Serial.begin(9600);
 for(int i = 0; i < dipCount; i++)
  pinmode(dip[i],INPUT_PULLUP);
}
void loop() 
{
  call(getMode());
  delay(1000);
}

// *********

inline void call(byte index) 
{
  ((FUNC*)pgm_read_word_near(&PointerFeld[index]))();
}

uint8_t getMode(void)
{
  uint8_t retValue = 0;
  for(uint8_t ct = 0; ct < dipCount; ct++)
    retValue |= digitalRead(dip[ct])<<ct;
  return retValue;
}



void f0() 
{
  Serial.println("F0");
}

void f1() 
{
  Serial.println("F1");
}

void f2() 
{
  Serial.println("F2");
}

void f3() 
{
  Serial.println("F3");
}

Edit, sehe gerade, ich habe den return vergessen :wink:
@Combie, das mit 4 Funktionen bei nur 2 Schaltern ist korrekt. Anzahl an Funktionen 2 hoch Anzahl Schaltern. Macht bei den 8 Stk insgesamt 256 Möglichkeiten. Ob der TE soviele wirklich braucht? Wenn dir 64 Möglichkeiten reichen, kannst du auch Pin 2 - 7 direkt einlesen.

uint8_t mode = PINA>>2;
const uint8_t dipCount = 8;[color=#222222][/color]
const uint8_t dip[dipCount] = {2, 3, 4, 5, 6, 7, 8};[color=#222222][/color]
uint8_t getMode(void)[color=#222222][/color]
{[color=#222222][/color]
	uint8_t retValue = 0;[color=#222222][/color]
	[color=#222222][/color]
	for(uint8_t ct = 0; ct < dipCount; ct++)[color=#222222][/color]
	{[color=#222222][/color]
		retValue |= digitalRead(dip[ct]);[color=#222222][/color]
	}
	return retValue;[color=#222222][/color]
}[color=#222222][/color]

@Combie, insgesamt sollten bei 8 Dip-Schaltern 256 Möglichkeiten zur Verfügung stehen :wink:

Hi ich brauche natürlich keine 256 möglichkeiten der 8 bin Dip is nur gekauft worden bzw bestellt weil ich das ja anfangs alles einzeln eingelesen habe und mit so Arbeit sparen wollte da ich dann schonmal 8 Schalter habe ohne viel zu schreiben :wink: .Also aus reiner Faulheit ^^ in der Version reicht ein 4 Dip Vollkommen aus . Werde dennoch den 8er nutzen da er na nun schon bezahlt ist ;).

Und beim nächstenmal gibts dann gleich kleinere.

Danke für all eure Hilfe .Dann werd ich jetzt mal den Software Teil zusammenschreiben . Und Morgen (sofern er dann kommt) den HardwareTeil.

@sschultewolter
Du nutzt nur 7 Inputs.......
Da wirds schwierig mit 8 Schaltern und den 256 Funktionen.
Und da fehlt ein schieben in deiner Funktion.
Das Return war natürlich wichtig.

Ansonsten:
Ich habs auf 4 Funktionen (2 Schalter) begrenzt, ist ja nur ein Beispiel....
Die mögliche Anzahl steigt in 2er Potenz Schritten.
Leerstellen sollte man im Array mit Dummy Funktionen füllen, damit keine null Pointer auftreten.

HotSystems:
Ja, ok. Ist wirklich nur ein Alternative zur obigen Lösung, aber recht effektiv, da man ja auch Ports am Arduino spart und bei einen 8Port Baustein PCF 8574 volle 8Bit (256 Eingänge) zur Verfügung hat.

Das sind nicht 256 Eingänge sondern 256 verschiedene Möglichkeiten

Grüße Uwe

uwefed:
Das sind nicht 256 Eingänge sondern 256 verschiedene Möglichkeiten

Grüße Uwe

Ja, stimmt. Falsch beschrieben.