Forum: Mikrocontroller und Digitale Elektronik Variable mit einem Wertebereich von 0 - 359


von Sebbi (Gast)


Lesenswert?

Hallo,

ich bin gerade am überlegen, wie ich folgendes am besten lösen kann.

Gegeben ist eine Variable "hue".

Wobei hier "hue" für den Farbton im HSV-System gilt. Angegeben wird das 
ganze von 0 - 359°. Dieses möchte ich einem C-Programm beibehalten. 
Anders als in einigen Libs (FastLed/Arduino), möchte ich den Wert nicht 
herunterskalieren auf ein Byte (0 - 255).

So, nun zu der eigentlich Frage, wo ich gerade meinen Kopf am rauchen 
habe.

Ich möchte bei einem Farbwechsel den kürzesten Weg gehen. Die Bewegung 
erfolgt in 1er Schritten (evtl. erweiterbar auch größere 
Schrittbereiche).


Fall 1:
Ist: 119°
Soll: 150°

Hier wird inkrementiert, da der Weg von 119° nach 150° deutlich kürzer 
ist, als wenn ich von 119° nach 0° und von 359° nach 150° mich bewege.

Wie kann ich dieses am besten in C erledigen?

Gibt es evtl. einen typ, den man selber bestimmen kann?
Also alles was über 359 geht, wird automatisch 0 (bei unsigned)

von Ingenieur (Gast)


Lesenswert?

Wenn das vernüftig funktionieren soll, müssen auch negative Werte und 
solche bis 719 als Zwischenergebnis zulässig sein.

Wenn die Rechnung exakt sein soll, muss man mindestens 2 Bit besser 
sein, als die Auflösung, damit die Rundung der Zwischenergebnisse immer 
stimmig ist. Damit braucht es 720x2x4= range 2048 / 11 Bit. Das 
Umbrechen der Variable muss dann manuell erfolgen.

von scherzkeks (Gast)


Lesenswert?

Wenn Du 16bit als Variable nehmen kannst, kannst Du mittels Modulo den 
Bereich auf Deine Werte begrenzen.
Ansonsten mußt Du selber "basteln" ...

von Sebbi (Gast)


Lesenswert?

Eine 16-bit Wert habe ich auf dem AVR dafür schon belegt, da 359 nicht 
in einem uint8_t reinpasst ;)

von hauspapa (Gast)


Lesenswert?

>Wie kann ich dieses am besten in C erledigen?Wie kann ich dieses am besten >in C 
erledigen?

evtl. etwas hölzern und  man müsste schauen ob gegen 179 oder 180 zu 
prüfen ist, aber im Prinzip sollte folgendes gehen:

if(((ist>soll)&&((ist-soll)<180))||((ist<soll)&&((soll-ist)>180)))
 {
 abwärts_zählen();
 }
else
 {
 if(ist==soll)
  {
  mach_nichts();
  }
 else
 {
 aufwärts_zählen();
 }
}

bei 0/359 noch ein Vergleich mit Sprung zu 359/0 und gut.

viel Erfolg
hauspapa

von B. S. (bestucki)


Lesenswert?

Sebbi schrieb:
> Fall 1:
> Ist: 119°
> Soll: 150°

Wenn es nur darum geht, den kürzeren Weg zu finden, sollte das Problem 
einfach zu lösen sein:
1
int BerechneDrehrichtung(
2
  int Ist,
3
  int Soll
4
){
5
  static const int AnzahlSchritte = 360;
6
  
7
  if(Ist == Soll){
8
    return 0; /* nix zu tun */
9
  }
10
  
11
  int SchritteCW = Soll - Ist;
12
  if(SchritteCW < 0){
13
    SchritteCW += AnzahlSchritte; /* kuenstlicher Unterlauf */
14
  }
15
  
16
  if(SchritteCW < (AnzahlSchritte / 2)){
17
    return 1; /* drehe im Uhrzeigersinn */
18
  }
19
  else{
20
    return -1; /* drehe gegen den Uhrzeigersinn */
21
  }
22
}
23
24
25
int main(void){
26
  int Ist, Soll, Drehrichtung;
27
  while(Drehrichtung = BerechneDrehrichtung(Ist, Soll)){
28
    Ist += Drehrichtung;
29
  }
30
  return 0;
31
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.