Forum: Mikrocontroller und Digitale Elektronik Wie macht man solche Lichtmodes? Lauflicht, PWM und Co


von Daniel (Gast)


Lesenswert?

Hallo,

Wie baut man solche Lichtmodes wie manche mit ihren Boards machen?

Also sagen wir mal, wir haben eine 14 CH PWM.

Und nun will man so Sachen wie.. Dimme eine nach der anderen auf... Wenn 
alle an sind.. Dimme wieder zurück...

Oder dimme nach und nach auf... Also wenn die erste bei 10% ist starte 
die nächste so das die alle nach und nach immer heller werden und eben 
solche "Effekte"

Gleiches mit RGB.. Wie z.b. Rainbow und Co... Wie macht man all solche 
Effekte?

von Andre (Gast)


Lesenswert?

Mit ein paar verschachtelten Schleifen.

von Harald (Gast)


Lesenswert?

In den Arduino-Beispielprojekten, die immer mit dem Treiber zusammen 
kommen, kannst Du Dir einiges abschauen.

von c-hater (Gast)


Lesenswert?

Andre schrieb:

> Mit ein paar verschachtelten Schleifen.

Das ist nur eine der vielen Möglichkeiten und fast nie die Beste. 
Insbesondere dann nicht, wenn's außer der Ablaufsteuerung für die LEDs 
auch noch anderes zu tun gibt.

von Wolfgang (Gast)


Lesenswert?

Daniel schrieb:
> Wie baut man solche Lichtmodes wie manche mit ihren Boards machen?

Das kommt auf die Boards an.

von Der Zahn der Zeit (🦷⏳) (Gast)


Lesenswert?

Eine furchtbar allgemeine Frage. Nur weil du als einzigen Anmerkung "14 
CH PWM" schreibst, kann ich mir die Antwort "z. B. mit Analogtechnik" 
sparen.

Ansonsten in reiner Digitaltechnik, z. B. diskret oder mit einem FPGA, 
oder mit einem µC, dann mit Software.

Ja, das ist die Antwort: Mit Software.

(Was würdest du z. B. auf die Frage "Wie macht man Musik, z. B. mit 14 
Geigen?" antworten?)

von Schlaumaier (Gast)


Lesenswert?

Die schnellste Methode.

Arduino-Starterset kaufen.

Arduino-IDE laden und installieren

Blinki laden (ist in der IDE dabei)

Übertragen  und zuschauen wie es blinkt ;)

Dann das Programm verstehen und erweitern.

Diese Anleitung ist KEIN Witz.

von Andre (Gast)


Lesenswert?

c-hater schrieb:
> Das ist nur eine der vielen Möglichkeiten und fast nie die Beste.

Dafür aber die verständlichste.
Wenn es noch mehr zu tun gibt, würde ich daraus entweder eine 
Statemachine mit Zählvariablen machen und die regelmäßig aufrufen, oder 
die Kommunikation in einen Timer Interrupt verpacken.

von Daniel (Gast)


Lesenswert?

Also das PCB ist von mir selbst entwickelt und kann man in einem anderen 
Beitrag sehen.

Ist nen ATMega128 der 32 Software PWMs macht.

Per i2c kommen einfach die Werte in der Form channel value

Also z.b

Start Adresse + write
Write Channelnummer
Write value
Stop

Danach ändert der entsprechende channel den pwm Wert.

Das klappt soweit....

Den 32ch slave wollte ich aber dynamischer machen und nicht nur die 
einzelnen pwm channel Werte ändern sondern auch um Effekte erweitern..

Also man sagt effekt bla... Und er macht das dann...

Und eben solche Dinge.

von Daniel (Gast)


Lesenswert?


von Peter D. (peda)


Lesenswert?

Die flexible Lösung sind mehrere Arrays mit Leuchtmuster.
Hier mal das Prinzip:

Beitrag "Re: AVR Sleep Mode / Knight Rider"

von Horst M. (horst)


Lesenswert?

Daniel schrieb:
> Und nun will man so Sachen wie.. Dimme eine nach der anderen auf... Wenn
> alle an sind.. Dimme wieder zurück...
>
> Oder dimme nach und nach auf... Also wenn die erste bei 10% ist starte
> die nächste so das die alle nach und nach immer heller werden und eben
> solche "Effekte"
>
> Gleiches mit RGB.. Wie z.b. Rainbow und Co... Wie macht man all solche
> Effekte?

Keine Ahnung, ob's Dir viel nützt, aber hier sind solche Effekte 
implementiert:
Beitrag "AVR Soft-PWM mit max. 256 LEDs"

Ist evtl. zumindest ein Denkanstoß, wie man sowas ziemlich flexibel 
mittels Tabellenstrukturen machen kann.
Am Ende des Posts ist ein Video verlinkt, da bekommst Du einen Eindruck, 
wie das am Ende aussehen kann.

von Axel S. (a-za-z0-9)


Lesenswert?

Daniel schrieb:

> Wie baut man solche Lichtmodes wie manche mit ihren Boards machen?

Indem man sie programmiert?

> Also sagen wir mal, wir haben eine 14 CH PWM.
>
> Und nun will man so Sachen wie.. Dimme eine nach der anderen auf... Wenn
> alle an sind.. Dimme wieder zurück...

Ist das eine Fangfrage? Da gibt es so viele Wege, das zu programmieren 
wie es Programmierer gibt.

Hardcodiert als Schleifen (Anfäger gern auch aufgerollte Schleifen mit 
eingestreuten delay_ms). Oder mit Tabellen. Als endlicher Automat 
(Finite State Machine), usw. usf. Oder Kombinationen daraus.

Ganz hartgesottene bauen einen universellen "Player" für vorgefertige 
"Programme" (sprich: Tabellen) und machen sich eine App zum Erzeugen 
dieser Programme.

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Axel S. schrieb:

> Ganz hartgesottene bauen einen universellen "Player" für vorgefertige
> "Programme" (sprich: Tabellen) und machen sich eine App zum Erzeugen
> dieser Programme.

Das ist definitiv die beste und universellste Variante. Und bei 
entsprechend brauchbarer Gestaltung des "Tabellengenerators" auch die 
mit Abstand am einfachsten zu benutzende.

Allerdings: bei aufwendigen Animationen kann die schiere Größe so einer 
Tabelle auch schonmal dazu zwingen, auf größere Controller auszuweichen 
oder externe Massenspeicher (z.B. SD-Card) anzuflanschen.

von Stefan (Gast)


Angehängte Dateien:

Lesenswert?

Andre schrieb:
> Dafür aber die verständlichste.
Für menschliche Anwender ist die verständlichste Möglichkeit unter den 
vielen Tabellarischen i.A. die beste Möglichkeit (sonst brauchen Käufer 
schnell für 32 Kanäle einen Controller mit SD-Card, während bei 
angemessener Programierung ein Mega16 bis auf einen fehlenden Pin 
ausreicht)   ;-).

Daniel schrieb:
> Also man sagt effekt bla... Und er macht das dann...
Es sollen also eine kleine Anzahl von Abläufen/Progrämmchen mit eher 
kleinen Anforderungen an lokale Variablen, die die meiste Zeit mit 
warten beschäftigt sind, gestartet werden.
--> simple Poly-Task d.h. statische Anzahl von Slots und Variablen 
(bspw.A-F) je Slot/Ablauf/Programm.
(u.U. etwas aufwändigeres) Fading lässt sich am simpelsten in festen 
Intervallen für alle Kanäle gemeinsam realisieren.
Für das Beispiel gäbe es dann ungefähr (aus Anhang mit korrigierter 
C-Syntax und anderen Fehlern)
1
void aufleuchten() __attribut__(OS_task) {
2
  for(*tsk.A=1,14,*tsk.A++){
3
    fadeA[*tsk.A].des=UINT_MAX;
4
    fadeA[*tsk.A].delta=100;
5
    fadeA[*tsk.A].modus=0;
6
    while(fadeA[*tsk.A].cur<0.10*UINT_MAX){yield;}
7
    }
8
  while(fadeA[14],cur<UINT_MAX){yield;}
9
  *tsk.adr=NULL; 
10
  }
mit einem reservierten Slot bspw. 0 lassen sich Abläufe reihen:
1
void combi1() __attribut__(OS_task) {
2
  slotA[0].adr=&aufleuchten; while(slotA[0].adr!=NULL){yield;}
3
  slotA[0].adr=&ausgehen;    while(slotA[0].adr!=NULL){yield;}
4
  *tsk.adr=NULL; 
5
  }
usw.
Aufruf halt durch kopieren der Startadresse in das .adr Feld (kann auch 
laufende Makros ablösen) Von Außen über den Index einer Tabelle mit den 
Progrämmchen. Wenn man
- keine echten lokale variablen verwendet
- keine blockierenden Funktionen nutzt d.h. statt delay die zielzeit in 
*tsk.x speichert und in yield schleife überprüft
ist das Konstrukt auch pflegeleicht und so flexibel, dass sich diverse 
Tabelleninterpreter als sub-flexibilität 'bedienen'(sprich: 
programmieren) lassen.

von Daniel (Gast)


Lesenswert?

Danke...

Also der Code ist sehr hoch... Da verstehe ich nicht wirklich viel 
von...

Also.. Ich habe derzeit ein Board mit einem ATMega128A.

Der ATMega erzeugt 32 PWM Kanäle. Der komplette PortA, PortB, PortC und 
PortE laufen als PWM.

Ich habe dazu den Software PWM Code hier aus dem AVR-GCC Tutorial von 8 
auf 32 CH geändert.

Dieser läuft mit Timer1.

Nachdem alle 32 PWMs funktionierten habe ich Timer0 im 10ms Interrupt 
eingestellt.

Mit diesem erzeuge ich meine Zeitbasis für meine PWMs um diese zu 
dimmen.

In etwa so
1
#define TIMER_FREQ 10
2
int...... 
3
.... 
4
...
5
6
7
while() {..... 
8
  if ( sysTimer % (CH1_SPEED * TIMER_FREQ) == 0 ) {
9
    if (CH1_SOLL < CH1_IS) {
10
      CH1_IS--;
11
    }
12
    if (CH1_SOLL > CH1_IS) {
13
      CH1_IS++;
14
    }
15
  }
16
..... 
17
..... 
18
pwm Code..... 
19
}

ich brauche nun nur CH1_SOLL ändern und die pwm ändert sich gedimmt.. 
Also heisst das auf und ab gedimmt?

Wenn ich CH1_SPEED ändere... Kann ich die Dimmgeschwindigkeit ändern.

Dafür habe ich mir nen riesen array gebaut...
1
pwmmode[modenum][chnum][value][speed];

Das fülle ich... Über eine Funktion bin ich soweit... Das ich einfach 
den "Mode" ändere... Und dann werden die Daten aus dem array in die 
Daten für die pwm geschrieben...

Das klappt alles wunderbar... Die Werte in dem array kann ich per uart 
editieren. Auch per i2c kann ich die Daten schreiben...

Die pwm ändert sich dementsprechend...

Wenn ich das nun richtig verstanden habe... Soll ich nun meine Tabelle 
(das array) nehmen... Und das laufend verändern?! Richtig?

Also nicht ich sende per uart die änderungen sondern das macht der uc.

Richtig?

von Daniel (Gast)


Lesenswert?

Bzw.. Hier mal mein Code..
1
#include "../header/system.h"
2
3
int main(void) {
4
  
5
  wdt_disable();
6
  
7
  // Initialisiere System LED (Status LED)
8
  stateled_init();
9
  systemstate = STATE_IDLE;
10
  
11
  // Initialisiere I2C
12
  i2c_readaddr_init();
13
  init_twi_slave(i2c_readaddr());  
14
  
15
  // Initialisiere PWM Channels
16
  channels_init();
17
  
18
  // Initialisiere PWM Timer
19
  pwmtimer_init();
20
  
21
  // Initialisiere PWM Modes
22
  modes_init();
23
  
24
  softreset = 0;
25
  
26
  // Enable Watchdog
27
  wdt_enable(WDTO_2S);
28
  
29
  // EEPROM
30
  if (getEEDefaultExist() != (uint16_t) eeDataDefaultExist) {
31
     eeprom_write_default_data();
32
  }
33
  
34
  systemTimer_init();
35
  
36
  ismode = 0;
37
  runmode = 1;
38
  
39
  sei();
40
  
41
  systemstate = STATE_RUN;
42
  
43
  while (1) {
44
     
45
     if (softreset == 0) {
46
      wdt_reset();
47
     }
48
     
49
     if (RUNPWM == 1) {
50
       channels_run();
51
    }
52
     
53
     channels_update();
54
     
55
     // Systemled
56
    stateled();
57
    // Systemled end
58
     
59
    // System
60
    if (ismode != runmode || modedatachange == 1) {
61
      for (int i = 0; i < 32; i++) {
62
        pwm[i][0] = pwmmode[runmode][i][0];
63
      }
64
      modedatachange = 0;
65
      ismode = runmode;
66
    }
67
    
68
    if (i2cbuf != 0) {
69
      
70
      switch(i2cdata[1]) {
71
72
         case 1:                              // Change Channel Value in selected Mode  | 1, Change, Modenumber, Channelnumber, Value(0-PWM_STEPS(255))
73
                                             // 1 1 1 (Mode) 1 (Channel) 100 (Value)
74
            i2cmodenr = i2cdata[2];
75
            i2cchnr = i2cdata[3];
76
            i2cpwmval = i2cdata[4];
77
            if (i2cmodenr >= 1 && i2cmodenr <= PWMMODENUMS && i2cchnr >= 1 && i2cchnr <= CHANNELNUMS && i2cpwmval >= 0 && i2cpwmval <= PWM_STEPS) {
78
              i2cchnr = i2cchnr - 1;
79
              
80
              set_pwmmode_value(i2cmodenr, i2cchnr, i2cpwmval);
81
              
82
              if (runmode == i2cmodenr) {
83
                modedatachange = 1;
84
              }
85
            }
86
            
87
           break;
88
           
89
         case 2:                              // Change Runmode  | 1, Change, Modenumber
90
                                             // 1 2 1 (Mode)
91
            if (i2cdata[2] >= 0 && i2cdata[2] <= PWMMODENUMS) {
92
              runmode = i2cdata[2];
93
            }
94
            
95
           break;
96
           
97
         case 3:                              // Change Channel Changespeed in selected Mode  | 1, Changespeed, Modenumber, Channelnumber, Speed(Val * TIMERFREQ))
98
                                             // 1 3 1 (Mode) 1 (Channel) 3 (Speed) 
99
            i2cmodenr = i2cdata[2];
100
            i2cchnr = i2cdata[3];
101
            i2cpwmval = i2cdata[4];
102
            if (i2cmodenr >= 1 && i2cmodenr <= PWMMODENUMS && i2cchnr >= 1 && i2cchnr <= CHANNELNUMS && i2cpwmval >= 1 && i2cpwmval <= 100) {
103
              i2cchnr = i2cchnr - 1;
104
              
105
              set_pwmmode_speed(i2cmodenr, i2cchnr, i2cpwmval);
106
              
107
              if (runmode == i2cmodenr) {
108
                modedatachange = 1;
109
              }
110
            }
111
            
112
           break;
113
           
114
         case 4:                              // Change Channel Changemode in selected Mode  | 1, Changespeed, Modenumber, Channelnumber, Changemode (1 = Soft, 2 = Hard)
115
                                             // 1 4 1 (Mode) 1 (Channel) 1 (Changemode) 
116
            i2cmodenr = i2cdata[2];
117
            i2cchnr = i2cdata[3];
118
            i2cpwmval = i2cdata[4];
119
            if (i2cmodenr >= 1 && i2cmodenr <= PWMMODENUMS && i2cchnr >= 1 && i2cchnr <= CHANNELNUMS && i2cpwmval >= 1 && i2cpwmval <= 2) {
120
              i2cchnr = i2cchnr - 1;
121
              
122
              set_pwmmode_changemode(i2cmodenr, i2cchnr, i2cpwmval);
123
              
124
              if (runmode == i2cmodenr) {
125
                modedatachange = 1;
126
              }
127
            }
128
            
129
           break;
130
           
131
         case 8:                              // Reboot
132
                                             // 1 8 1
133
            if (i2cdata[2] == 1) {
134
              softreset = 1;
135
            }
136
            break;
137
           
138
         case 9:                              // Factory Reset
139
                                             // 1 9 1
140
            if (i2cdata[2] == 1) {
141
              eeprom_write_default(56);
142
              softreset = 1;
143
           }
144
            break;
145
            
146
         default:
147
           break;
148
       }
149
      i2cbuf = 0;
150
    }
151
  
152
  }
153
154
}

und die Datei die das hauptsächliche macht.. channels.c
1
#include "../header/system.h"
2
3
void channels_init(void) {
4
5
  PWM_DDRA = 0xFF;         // Port als Ausgang
6
  PWM_DDRB = 0xFF;
7
  PWM_DDRC = 0xFF;
8
  PWM_DDRE = 0xFF;
9
  
10
  PWM_PORTA &= ~(1<<PA0);
11
  PWM_PORTA &= ~(1<<PA1);
12
  PWM_PORTA &= ~(1<<PA2);
13
  PWM_PORTA &= ~(1<<PA3);
14
  PWM_PORTA &= ~(1<<PA4);
15
  PWM_PORTA &= ~(1<<PA5);
16
  PWM_PORTA &= ~(1<<PA6);
17
  PWM_PORTA &= ~(1<<PA7);
18
  
19
  PWM_PORTB &= ~(1<<PB0);
20
  PWM_PORTB &= ~(1<<PB1);
21
  PWM_PORTB &= ~(1<<PB2);
22
  PWM_PORTB &= ~(1<<PB3);
23
  PWM_PORTB &= ~(1<<PB4);
24
  PWM_PORTB &= ~(1<<PB5);
25
  PWM_PORTB &= ~(1<<PB6);
26
  PWM_PORTB &= ~(1<<PB7);
27
  
28
  PWM_PORTC &= ~(1<<PC0);
29
  PWM_PORTC &= ~(1<<PC1);
30
  PWM_PORTC &= ~(1<<PC2);
31
  PWM_PORTC &= ~(1<<PC3);
32
  PWM_PORTC &= ~(1<<PC4);
33
  PWM_PORTC &= ~(1<<PC5);
34
  PWM_PORTC &= ~(1<<PC6);
35
  PWM_PORTC &= ~(1<<PC7);
36
  
37
  PWM_PORTE &= ~(1<<PE0);
38
  PWM_PORTE &= ~(1<<PE1);
39
  PWM_PORTE &= ~(1<<PE2);
40
  PWM_PORTE &= ~(1<<PE3);
41
  PWM_PORTE &= ~(1<<PE4);
42
  PWM_PORTE &= ~(1<<PE5);
43
  PWM_PORTE &= ~(1<<PE6);
44
  PWM_PORTE &= ~(1<<PE7);
45
  
46
  for (int i = 0; i < 32; i++) {
47
    pwm[i][0] = 0;    // PWM Value
48
  }
49
  
50
  PWM_CH1_IS = 0;
51
  PWM_CH2_IS = 0;
52
  PWM_CH3_IS = 0;
53
  PWM_CH4_IS = 0;
54
  PWM_CH5_IS = 0;
55
  PWM_CH6_IS = 0;
56
  PWM_CH7_IS = 0;
57
  PWM_CH8_IS = 0;
58
59
  PWM_CH9_IS = 0;
60
  PWM_CH10_IS = 0;
61
  PWM_CH11_IS = 0;
62
  PWM_CH12_IS = 0;
63
  PWM_CH13_IS = 0;
64
  PWM_CH14_IS = 0;
65
  PWM_CH15_IS = 0;
66
  PWM_CH16_IS = 0;
67
68
  PWM_CH17_IS = 0;
69
  PWM_CH18_IS = 0;
70
  PWM_CH19_IS = 0;
71
  PWM_CH20_IS = 0;
72
  PWM_CH21_IS = 0;
73
  PWM_CH22_IS = 0;
74
  PWM_CH23_IS = 0;
75
  PWM_CH24_IS = 0;
76
77
  PWM_CH25_IS = 0;
78
  PWM_CH26_IS = 0;
79
  PWM_CH27_IS = 0;
80
  PWM_CH28_IS = 0;
81
  PWM_CH29_IS = 0;
82
  PWM_CH30_IS = 0;
83
  PWM_CH31_IS = 0;
84
  PWM_CH32_IS = 0;
85
}
86
87
void channels_update(void) {
88
89
  switch (OUTSORTING) {
90
    case 1:
91
     // PA0
92
      pwm_settingA[0] = PWM_CH1_IS;
93
      // PA1
94
      pwm_settingA[1] = PWM_CH2_IS;
95
      // PA2
96
      pwm_settingA[2] = PWM_CH3_IS;
97
      // PA3
98
      pwm_settingA[3] = PWM_CH4_IS;
99
      // PA4
100
      pwm_settingA[4] = PWM_CH5_IS;
101
      // PA5
102
      pwm_settingA[5] = PWM_CH6_IS;
103
     // PA6
104
      pwm_settingA[6] = PWM_CH7_IS;
105
      // PA7
106
      pwm_settingA[7] = PWM_CH8_IS;
107
  
108
      // PC0
109
      pwm_settingC[0] = PWM_CH6_IS;
110
      // PC1
111
      pwm_settingC[1] = PWM_CH15_IS;
112
      // PC2
113
      pwm_settingC[2] = PWM_CH14_IS;
114
      // PC3
115
      pwm_settingC[3] = PWM_CH13_IS;
116
      // PC4
117
      pwm_settingC[4] = PWM_CH12_IS;
118
      // PC5
119
      pwm_settingC[5] = PWM_CH11_IS;
120
      // PC6
121
      pwm_settingC[6] = PWM_CH10_IS;
122
      // PC7
123
      pwm_settingC[7] = PWM_CH9_IS;
124
  
125
      // PB0
126
      pwm_settingB[0] = PWM_CH24_IS;
127
      // PB1
128
      pwm_settingB[1] = PWM_CH23_IS;
129
     // PB2
130
      pwm_settingB[2] = PWM_CH22_IS;
131
      // PB3
132
      pwm_settingB[3] = PWM_CH21_IS;
133
      // PB4
134
      pwm_settingB[4] = PWM_CH20_IS;
135
      // PB5
136
      pwm_settingB[5] = PWM_CH19_IS;
137
      // PB6
138
      pwm_settingB[6] = PWM_CH18_IS;
139
      // PB7
140
      pwm_settingB[7] = PWM_CH17_IS;
141
  
142
      // PE0
143
      pwm_settingE[0] = PWM_CH32_IS;
144
      // PE1
145
      pwm_settingE[1] = PWM_CH31_IS;
146
      // PE2
147
      pwm_settingE[2] = PWM_CH30_IS;
148
      // PE3
149
      pwm_settingE[3] = PWM_CH29_IS;
150
      // PE4
151
      pwm_settingE[4] = PWM_CH28_IS;
152
      // PE5
153
      pwm_settingE[5] = PWM_CH27_IS;
154
      // PE6
155
      pwm_settingE[6] = PWM_CH26_IS;
156
      // PE7
157
      pwm_settingE[7] = PWM_CH25_IS;
158
      break;
159
    
160
    case 2:
161
     // PA0
162
      pwm_settingA[0] = PWM_CH1_IS;
163
      // PA1
164
      pwm_settingA[1] = PWM_CH17_IS;
165
      // PA2
166
      pwm_settingA[2] = PWM_CH2_IS;
167
      // PA3
168
      pwm_settingA[3] = PWM_CH18_IS;
169
      // PA4
170
      pwm_settingA[4] = PWM_CH3_IS;
171
      // PA5
172
      pwm_settingA[5] = PWM_CH19_IS;
173
     // PA6
174
      pwm_settingA[6] = PWM_CH4_IS;
175
      // PA7
176
      pwm_settingA[7] = PWM_CH20_IS;
177
  
178
      // PC0
179
      pwm_settingC[0] = PWM_CH24_IS;
180
      // PC1
181
      pwm_settingC[1] = PWM_CH8_IS;
182
      // PC2
183
      pwm_settingC[2] = PWM_CH23_IS;
184
      // PC3
185
      pwm_settingC[3] = PWM_CH7_IS;
186
      // PC4
187
      pwm_settingC[4] = PWM_CH22_IS;
188
      // PC5
189
      pwm_settingC[5] = PWM_CH6_IS;
190
      // PC6
191
      pwm_settingC[6] = PWM_CH21_IS;
192
      // PC7
193
      pwm_settingC[7] = PWM_CH5_IS;
194
  
195
      // PB0
196
      pwm_settingB[0] = PWM_CH28_IS;
197
      // PB1
198
      pwm_settingB[1] = PWM_CH12_IS;
199
     // PB2
200
      pwm_settingB[2] = PWM_CH27_IS;
201
      // PB3
202
      pwm_settingB[3] = PWM_CH11_IS;
203
      // PB4
204
      pwm_settingB[4] = PWM_CH26_IS;
205
      // PB5
206
      pwm_settingB[5] = PWM_CH10_IS;
207
      // PB6
208
      pwm_settingB[6] = PWM_CH25_IS;
209
      // PB7
210
      pwm_settingB[7] = PWM_CH9_IS;
211
  
212
      // PE0
213
      pwm_settingE[0] = PWM_CH32_IS;
214
      // PE1
215
      pwm_settingE[1] = PWM_CH16_IS;
216
      // PE2
217
      pwm_settingE[2] = PWM_CH31_IS;
218
      // PE3
219
      pwm_settingE[3] = PWM_CH15_IS;
220
      // PE4
221
      pwm_settingE[4] = PWM_CH30_IS;
222
      // PE5
223
      pwm_settingE[5] = PWM_CH14_IS;
224
      // PE6
225
      pwm_settingE[6] = PWM_CH29_IS;
226
      // PE7
227
      pwm_settingE[7] = PWM_CH13_IS;
228
      break;
229
      
230
    default:
231
      // PA0
232
      pwm_settingA[0] = PWM_CH1_IS;
233
      // PA1
234
      pwm_settingA[1] = PWM_CH2_IS;
235
      // PA2
236
      pwm_settingA[2] = PWM_CH3_IS;
237
      // PA3
238
      pwm_settingA[3] = PWM_CH4_IS;
239
      // PA4
240
      pwm_settingA[4] = PWM_CH5_IS;
241
      // PA5
242
      pwm_settingA[5] = PWM_CH6_IS;
243
     // PA6
244
      pwm_settingA[6] = PWM_CH7_IS;
245
      // PA7
246
      pwm_settingA[7] = PWM_CH8_IS;
247
  
248
      // PC0
249
      pwm_settingC[0] = PWM_CH6_IS;
250
      // PC1
251
      pwm_settingC[1] = PWM_CH15_IS;
252
      // PC2
253
      pwm_settingC[2] = PWM_CH14_IS;
254
      // PC3
255
      pwm_settingC[3] = PWM_CH13_IS;
256
      // PC4
257
      pwm_settingC[4] = PWM_CH12_IS;
258
      // PC5
259
      pwm_settingC[5] = PWM_CH11_IS;
260
      // PC6
261
      pwm_settingC[6] = PWM_CH10_IS;
262
      // PC7
263
      pwm_settingC[7] = PWM_CH9_IS;
264
  
265
      // PB0
266
      pwm_settingB[0] = PWM_CH24_IS;
267
      // PB1
268
      pwm_settingB[1] = PWM_CH23_IS;
269
     // PB2
270
      pwm_settingB[2] = PWM_CH22_IS;
271
      // PB3
272
      pwm_settingB[3] = PWM_CH21_IS;
273
      // PB4
274
      pwm_settingB[4] = PWM_CH20_IS;
275
      // PB5
276
      pwm_settingB[5] = PWM_CH19_IS;
277
      // PB6
278
      pwm_settingB[6] = PWM_CH18_IS;
279
      // PB7
280
      pwm_settingB[7] = PWM_CH17_IS;
281
  
282
      // PE0
283
      pwm_settingE[0] = PWM_CH32_IS;
284
      // PE1
285
      pwm_settingE[1] = PWM_CH31_IS;
286
      // PE2
287
      pwm_settingE[2] = PWM_CH30_IS;
288
      // PE3
289
      pwm_settingE[3] = PWM_CH29_IS;
290
      // PE4
291
      pwm_settingE[4] = PWM_CH28_IS;
292
      // PE5
293
      pwm_settingE[5] = PWM_CH27_IS;
294
      // PE6
295
      pwm_settingE[6] = PWM_CH26_IS;
296
      // PE7
297
      pwm_settingE[7] = PWM_CH25_IS;
298
      break;
299
   }
300
      
301
}
302
303
void channels_run(void) {
304
305
  if (PWM_CH1_IS != pwm[CH1][0]) {
306
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH1) * TIMERFREQ) ) == 0) {
307
      if (get_pwmmode_changemode(runmode, CH1) == PWMCHANGESOFT) {
308
        if (PWM_CH1_IS > pwm[CH1][0]) {
309
          PWM_CH1_IS--;
310
        } else {
311
          PWM_CH1_IS++;
312
        }
313
      } else {
314
        PWM_CH1_IS = pwm[CH1][0];
315
      }
316
    }
317
  }
318
319
  if (PWM_CH2_IS != pwm[CH2][0]) {
320
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH2) * TIMERFREQ) ) == 0) {
321
      if (get_pwmmode_changemode(runmode, CH2) == PWMCHANGESOFT) {
322
        if (PWM_CH2_IS > pwm[CH2][0]) {
323
          PWM_CH2_IS--;
324
        } else {
325
          PWM_CH2_IS++;
326
        }
327
      } else {
328
        PWM_CH2_IS = pwm[CH2][0];
329
      }
330
    }
331
  }
332
333
  if (PWM_CH3_IS != pwm[CH3][0]) {
334
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH3) * TIMERFREQ) ) == 0) {
335
      if (get_pwmmode_changemode(runmode, CH3) == PWMCHANGESOFT) {
336
        if (PWM_CH3_IS > pwm[CH3][0]) {
337
          PWM_CH3_IS--;
338
        } else {
339
          PWM_CH3_IS++;
340
        }
341
      } else {
342
        PWM_CH3_IS = pwm[CH3][0];
343
      }
344
    }
345
  }
346
347
  if (PWM_CH4_IS != pwm[CH4][0]) {
348
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH4) * TIMERFREQ) ) == 0) {
349
      if (get_pwmmode_changemode(runmode, CH4) == PWMCHANGESOFT) {
350
        if (PWM_CH4_IS > pwm[CH4][0]) {
351
          PWM_CH4_IS--;
352
        } else {
353
          PWM_CH4_IS++;
354
        }
355
      } else {
356
        PWM_CH4_IS = pwm[CH4][0];
357
      }
358
    }
359
  }
360
361
  if (PWM_CH5_IS != pwm[CH5][0]) {
362
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH5) * TIMERFREQ) ) == 0) {
363
      if (get_pwmmode_changemode(runmode, CH5) == PWMCHANGESOFT) {
364
        if (PWM_CH5_IS > pwm[CH5][0]) {
365
          PWM_CH5_IS--;
366
        } else {
367
          PWM_CH5_IS++;
368
        }
369
      } else {
370
        PWM_CH5_IS = pwm[CH5][0];
371
      }
372
    }
373
  }
374
375
  if (PWM_CH6_IS != pwm[CH6][0]) {
376
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH6) * TIMERFREQ) ) == 0) {
377
      if (get_pwmmode_changemode(runmode, CH6) == PWMCHANGESOFT) {
378
        if (PWM_CH6_IS > pwm[CH6][0]) {
379
          PWM_CH6_IS--;
380
        } else {
381
          PWM_CH6_IS++;
382
        }
383
      } else {
384
        PWM_CH6_IS = pwm[CH6][0];
385
      }
386
    }
387
  }
388
389
  if (PWM_CH7_IS != pwm[CH7][0]) {
390
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH7) * TIMERFREQ) ) == 0) {
391
      if (get_pwmmode_changemode(runmode, CH7) == PWMCHANGESOFT) {
392
        if (PWM_CH7_IS > pwm[CH7][0]) {
393
          PWM_CH7_IS--;
394
        } else {
395
          PWM_CH7_IS++;
396
        }
397
      } else {
398
        PWM_CH7_IS = pwm[CH7][0];
399
      }
400
    }
401
  }
402
403
  if (PWM_CH8_IS != pwm[CH8][0]) {
404
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH8) * TIMERFREQ) ) == 0) {
405
      if (get_pwmmode_changemode(runmode, CH8) == PWMCHANGESOFT) {
406
        if (PWM_CH8_IS > pwm[CH8][0]) {
407
          PWM_CH8_IS--;
408
        } else {
409
          PWM_CH8_IS++;
410
        }
411
      } else {
412
        PWM_CH8_IS = pwm[CH8][0];
413
      }
414
    }
415
  }
416
417
  if (PWM_CH9_IS != pwm[CH9][0]) {
418
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH9) * TIMERFREQ) ) == 0) {
419
      if (get_pwmmode_changemode(runmode, CH9) == PWMCHANGESOFT) {
420
        if (PWM_CH9_IS > pwm[CH9][0]) {
421
          PWM_CH9_IS--;
422
        } else {
423
          PWM_CH9_IS++;
424
        }
425
      } else {
426
        PWM_CH9_IS = pwm[CH9][0];
427
      }
428
    }
429
  }
430
431
  if (PWM_CH10_IS != pwm[CH10][0]) {
432
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH10) * TIMERFREQ) ) == 0) {
433
      if (get_pwmmode_changemode(runmode, CH10) == PWMCHANGESOFT) {
434
        if (PWM_CH10_IS > pwm[CH10][0]) {
435
          PWM_CH10_IS--;
436
        } else {
437
          PWM_CH10_IS++;
438
        }
439
      } else {
440
        PWM_CH10_IS = pwm[CH10][0];
441
      }
442
    }
443
  }
444
445
  if (PWM_CH11_IS != pwm[CH11][0]) {
446
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH11) * TIMERFREQ) ) == 0) {
447
      if (get_pwmmode_changemode(runmode, CH11) == PWMCHANGESOFT) {
448
        if (PWM_CH11_IS > pwm[CH11][0]) {
449
          PWM_CH11_IS--;
450
        } else {
451
          PWM_CH11_IS++;
452
        }
453
      } else {
454
        PWM_CH11_IS = pwm[CH11][0];
455
      }
456
    }
457
  }
458
459
  if (PWM_CH12_IS != pwm[CH12][0]) {
460
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH12) * TIMERFREQ) ) == 0) {
461
      if (get_pwmmode_changemode(runmode, CH12) == PWMCHANGESOFT) {
462
        if (PWM_CH12_IS > pwm[CH12][0]) {
463
          PWM_CH12_IS--;
464
        } else {
465
          PWM_CH12_IS++;
466
        }
467
      } else {
468
        PWM_CH12_IS = pwm[CH12][0];
469
      }
470
    }
471
  }
472
473
  if (PWM_CH13_IS != pwm[CH13][0]) {
474
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH13) * TIMERFREQ) ) == 0) {
475
      if (get_pwmmode_changemode(runmode, CH13) == PWMCHANGESOFT) {
476
        if (PWM_CH13_IS > pwm[CH13][0]) {
477
          PWM_CH13_IS--;
478
        } else {
479
          PWM_CH13_IS++;
480
        }
481
      } else {
482
        PWM_CH13_IS = pwm[CH13][0];
483
      }
484
    }
485
  }
486
487
  if (PWM_CH14_IS != pwm[CH14][0]) {
488
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH14) * TIMERFREQ) ) == 0) {
489
      if (get_pwmmode_changemode(runmode, CH14) == PWMCHANGESOFT) {
490
        if (PWM_CH14_IS > pwm[CH14][0]) {
491
          PWM_CH14_IS--;
492
        } else {
493
          PWM_CH14_IS++;
494
        }
495
      } else {
496
        PWM_CH14_IS = pwm[CH14][0];
497
      }
498
    }
499
  }
500
501
  if (PWM_CH15_IS != pwm[CH15][0]) {
502
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH15) * TIMERFREQ) ) == 0) {
503
      if (get_pwmmode_changemode(runmode, CH15) == PWMCHANGESOFT) {
504
        if (PWM_CH15_IS > pwm[CH15][0]) {
505
          PWM_CH15_IS--;
506
        } else {
507
          PWM_CH15_IS++;
508
        }
509
      } else {
510
        PWM_CH15_IS = pwm[CH15][0];
511
      }
512
    }
513
  }
514
515
  if (PWM_CH16_IS != pwm[CH16][0]) {
516
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH16) * TIMERFREQ) ) == 0) {
517
      if (get_pwmmode_changemode(runmode, CH16) == PWMCHANGESOFT) {
518
        if (PWM_CH16_IS > pwm[CH16][0]) {
519
          PWM_CH16_IS--;
520
        } else {
521
          PWM_CH16_IS++;
522
        }
523
      } else {
524
        PWM_CH16_IS = pwm[CH16][0];
525
      }
526
    }
527
  }
528
529
  if (PWM_CH17_IS != pwm[CH17][0]) {
530
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH17) * TIMERFREQ) ) == 0) {
531
      if (get_pwmmode_changemode(runmode, CH17) == PWMCHANGESOFT) {
532
        if (PWM_CH17_IS > pwm[CH17][0]) {
533
          PWM_CH17_IS--;
534
        } else {
535
          PWM_CH17_IS++;
536
        }
537
      } else {
538
        PWM_CH17_IS = pwm[CH17][0];
539
      }
540
    }
541
  }
542
543
  if (PWM_CH18_IS != pwm[CH18][0]) {
544
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH18) * TIMERFREQ) ) == 0) {
545
      if (get_pwmmode_changemode(runmode, CH18) == PWMCHANGESOFT) {
546
        if (PWM_CH18_IS > pwm[CH18][0]) {
547
          PWM_CH18_IS--;
548
        } else {
549
          PWM_CH18_IS++;
550
        }
551
      } else {
552
        PWM_CH18_IS = pwm[CH18][0];
553
      }
554
    }
555
  }
556
557
  if (PWM_CH19_IS != pwm[CH19][0]) {
558
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH19) * TIMERFREQ) ) == 0) {
559
      if (get_pwmmode_changemode(runmode, CH19) == PWMCHANGESOFT) {
560
        if (PWM_CH19_IS > pwm[CH19][0]) {
561
          PWM_CH19_IS--;
562
        } else {
563
          PWM_CH19_IS++;
564
        }
565
      } else {
566
        PWM_CH19_IS = pwm[CH19][0];
567
      }
568
    }
569
  }
570
571
  if (PWM_CH20_IS != pwm[CH20][0]) {
572
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH20) * TIMERFREQ) ) == 0) {
573
      if (get_pwmmode_changemode(runmode, CH20) == PWMCHANGESOFT) {
574
        if (PWM_CH20_IS > pwm[CH20][0]) {
575
          PWM_CH20_IS--;
576
        } else {
577
          PWM_CH20_IS++;
578
        }
579
      } else {
580
        PWM_CH20_IS = pwm[CH20][0];
581
      }
582
    }
583
  }
584
585
  if (PWM_CH21_IS != pwm[CH21][0]) {
586
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH21) * TIMERFREQ) ) == 0) {
587
      if (get_pwmmode_changemode(runmode, CH21) == PWMCHANGESOFT) {
588
        if (PWM_CH21_IS > pwm[CH21][0]) {
589
          PWM_CH21_IS--;
590
        } else {
591
          PWM_CH21_IS++;
592
        }
593
      } else {
594
        PWM_CH21_IS = pwm[CH21][0];
595
      }
596
    }
597
  }
598
599
  if (PWM_CH22_IS != pwm[CH22][0]) {
600
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH22) * TIMERFREQ) ) == 0) {
601
      if (get_pwmmode_changemode(runmode, CH22) == PWMCHANGESOFT) {
602
        if (PWM_CH22_IS > pwm[CH22][0]) {
603
          PWM_CH22_IS--;
604
        } else {
605
          PWM_CH22_IS++;
606
        }
607
      } else {
608
        PWM_CH22_IS = pwm[CH22][0];
609
      }
610
    }
611
  }
612
613
  if (PWM_CH23_IS != pwm[CH23][0]) {
614
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH23) * TIMERFREQ) ) == 0) {
615
      if (get_pwmmode_changemode(runmode, CH23) == PWMCHANGESOFT) {
616
        if (PWM_CH23_IS > pwm[CH23][0]) {
617
          PWM_CH23_IS--;
618
        } else {
619
          PWM_CH23_IS++;
620
        }
621
      } else {
622
        PWM_CH23_IS = pwm[CH23][0];
623
      }
624
    }
625
  }
626
627
  if (PWM_CH24_IS != pwm[CH24][0]) {
628
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH24) * TIMERFREQ) ) == 0) {
629
      if (get_pwmmode_changemode(runmode, CH24) == PWMCHANGESOFT) {
630
        if (PWM_CH24_IS > pwm[CH24][0]) {
631
          PWM_CH24_IS--;
632
        } else {
633
          PWM_CH24_IS++;
634
        }
635
      } else {
636
        PWM_CH24_IS = pwm[CH24][0];
637
      }
638
    }
639
  }
640
641
  if (PWM_CH25_IS != pwm[CH25][0]) {
642
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH25) * TIMERFREQ) ) == 0) {
643
      if (get_pwmmode_changemode(runmode, CH25) == PWMCHANGESOFT) {
644
        if (PWM_CH25_IS > pwm[CH25][0]) {
645
          PWM_CH25_IS--;
646
        } else {
647
          PWM_CH25_IS++;
648
        }
649
      } else {
650
        PWM_CH25_IS = pwm[CH25][0];
651
      }
652
    }
653
  }
654
655
  if (PWM_CH26_IS != pwm[CH26][0]) {
656
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH26) * TIMERFREQ) ) == 0) {
657
      if (get_pwmmode_changemode(runmode, CH26) == PWMCHANGESOFT) {
658
        if (PWM_CH26_IS > pwm[CH26][0]) {
659
          PWM_CH26_IS--;
660
        } else {
661
          PWM_CH26_IS++;
662
        }
663
      } else {
664
        PWM_CH26_IS = pwm[CH26][0];
665
      }
666
    }
667
  }
668
669
  if (PWM_CH27_IS != pwm[CH27][0]) {
670
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH27) * TIMERFREQ) ) == 0) {
671
      if (get_pwmmode_changemode(runmode, CH27) == PWMCHANGESOFT) {
672
        if (PWM_CH27_IS > pwm[CH27][0]) {
673
          PWM_CH27_IS--;
674
        } else {
675
          PWM_CH27_IS++;
676
        }
677
      } else {
678
        PWM_CH27_IS = pwm[CH27][0];
679
      }
680
    }
681
  }
682
683
  if (PWM_CH28_IS != pwm[CH28][0]) {
684
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH28) * TIMERFREQ) ) == 0) {
685
      if (get_pwmmode_changemode(runmode, CH28) == PWMCHANGESOFT) {
686
        if (PWM_CH28_IS > pwm[CH28][0]) {
687
          PWM_CH28_IS--;
688
        } else {
689
          PWM_CH28_IS++;
690
        }
691
      } else {
692
        PWM_CH28_IS = pwm[CH28][0];
693
      }
694
    }
695
  }
696
697
  if (PWM_CH29_IS != pwm[CH29][0]) {
698
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH29) * TIMERFREQ) ) == 0) {
699
      if (get_pwmmode_changemode(runmode, CH29) == PWMCHANGESOFT) {
700
        if (PWM_CH29_IS > pwm[CH29][0]) {
701
          PWM_CH29_IS--;
702
        } else {
703
          PWM_CH29_IS++;
704
        }
705
      } else {
706
        PWM_CH29_IS = pwm[CH29][0];
707
      }
708
    }
709
  }
710
711
  if (PWM_CH30_IS != pwm[CH30][0]) {
712
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH30) * TIMERFREQ) ) == 0) {
713
      if (get_pwmmode_changemode(runmode, CH30) == PWMCHANGESOFT) {
714
        if (PWM_CH30_IS > pwm[CH30][0]) {
715
          PWM_CH30_IS--;
716
        } else {
717
          PWM_CH30_IS++;
718
        }
719
      } else {
720
        PWM_CH30_IS = pwm[CH30][0];
721
      }
722
    }
723
  }
724
725
  if (PWM_CH31_IS != pwm[CH31][0]) {
726
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH31) * TIMERFREQ) ) == 0) {
727
      if (get_pwmmode_changemode(runmode, CH31) == PWMCHANGESOFT) {
728
        if (PWM_CH31_IS > pwm[CH31][0]) {
729
          PWM_CH31_IS--;
730
        } else {
731
          PWM_CH31_IS++;
732
        }
733
      } else {
734
        PWM_CH31_IS = pwm[CH31][0];
735
      }
736
    }
737
  }
738
739
  if (PWM_CH32_IS != pwm[CH32][0]) {
740
    if ( ( sysTimer % (get_pwmmode_speed(runmode, CH32) * TIMERFREQ) ) == 0) {
741
      if (get_pwmmode_changemode(runmode, CH32) == PWMCHANGESOFT) {
742
        if (PWM_CH32_IS > pwm[CH32][0]) {
743
          PWM_CH32_IS--;
744
        } else {
745
          PWM_CH32_IS++;
746
        }
747
      } else {
748
        PWM_CH32_IS = pwm[CH32][0];
749
      }
750
    }
751
  }
752
  
753
  RUNPWM = 0;
754
  
755
}

von Axel S. (a-za-z0-9)


Lesenswert?

Daniel schrieb:
> Bzw.. Hier mal mein Code..

Hast du Kasper mal daran gedacht, daß sich vielleicht nicht jeder durch 
deine (gefühlt) 1000 Zeilen Code durchscrollen will? Was glaubst du 
eigentlich, wozu es eine Dateianhang-Funktion gibt?

von Daniel (Gast)


Angehängte Dateien:

Lesenswert?

Hier dann mal der Code

von 900ss (900ss)


Lesenswert?

Weshalb tar und nicht die einzelnen Dateien? Es machen sich wie die 
Mühe, ein test runterzuladen und zu entpacken anstatt direkt den Code 
anzusehen. Dafür müssten die Dateien aber eben direkt angehängt sein.

von Daniel (Gast)


Angehängte Dateien:

Lesenswert?

Ok. Dann lade ich das nochmal hoch...

von Hugo H. (hugo_hu)


Lesenswert?

Mit Code - selbst erzeugt - oder z.B. per Arduino wunderbarisiert :-).

von Daniel D. (daniel_duesentrieb)


Lesenswert?

Was wie wo?

von Stefan F. (Gast)


Lesenswert?

Jetzt noch bitte mit vernünftiger/einheitlicher Einrückung ...

von Joachim S. (oyo)


Lesenswert?

Daniel schrieb:
> Und nun will man so Sachen wie.. Dimme eine nach der anderen auf... Wenn
> alle an sind.. Dimme wieder zurück...
>
> Oder dimme nach und nach auf... Also wenn die erste bei 10% ist starte
> die nächste so das die alle nach und nach immer heller werden und eben
> solche "Effekte"
>
> Gleiches mit RGB.. Wie z.b. Rainbow und Co... Wie macht man all solche
> Effekte?

Ich bin nicht ganz sicher, ob ich Deine Frage überhaupt richtig 
verstehe, aber vielleicht hilft Dir das Folgende trotzdem irgendwie:

Ich habe mehrere WS2812B-RGB-LED-Streifen, auf denen ich beliebige 
Effekte/Animationen darstellen wollte. Für diesen LED-Streifen habe ich 
mir eine kleine ESP-Mikrocontroller-basierte Controller-Platine gebaut; 
welcher Effekt bzw. welche Animation dargestellt wird, kann man per WLAN 
bzw. BLE ändern.

Wichtig war mir jedenfalls, dass ich nicht starr auf ein paar 
Effekte/Animationen beschränkt bin, die bereits beim Kompilieren der 
Firmware feststehen, sondern ich im laufenden Betrieb absolut jede 
denkbare Animation einstellen kann.

Ich habe das letztlich so gelöst: Jeder Effekte/jede Animationen ist 
eine in der Programmiersprache LUA geschriebene Funktion, die mehrere 
Parameter übergeben bekommt, z.B.:
- Die (stetig steigende) Nummer des aktuellen Frames (als Variable 
"frame_index")
- Den Index der LED (als Variable "led_index")
- Die Gesamtanzahl der LEDs auf dem LED-Streifen (als Variable 
"number_of_leds")

...und anhand dieser Parameter gibt die Funktion dann einfach den 
Farbwert zurück, den die entsprechende LED als nächstes anzeigen sollen. 
Und diese Funktion wird dann pro Frame genau einmal für jede LED 
aufgerufen - bei sagen wir 30 frames pro Sekunde und 100 LEDs auf dem 
LED-Streifen also 3000 mal pro Sekunde.

Den Programmcode für einen einfachen Effekt, der einfach nur den 
gesamten LED-Streifen statisch in rot leuchten lässt, könnte z.B. so 
aussehen:
1
return hsv(0, 0, 1)

Der Programmcode für einen einfachen Strobo-Effekt würde so aussehen:
1
return hsv(0, 0, (frame_index % 2))

Der Programmcode für einen "Einzelnder laufender roter Punkt"-Effekt 
würde ungefähr so aussehen:
1
return hsv(0, 1, (led_index == (frame_index % number_of_leds)) ? 1 : 0)

Der Programmcode für einen Regenbogen-Effekt würde ungefähr so aussehen:
1
return hsv((360 * led_index / number_of_leds), 1, 1)

Aber auch ein "Knight Rider"-Effekt oder jeder andere Effekt wäre damit 
problemlos möglich.

Also kurz gesagt, ich habe für die einzelnen Effekte keine Tabellen, 
sondern jeder Effekt ist bei mir einfach eine Funktion, die für jede LED 
aufgerufen wird, und die dann anhand der übergebenen Parameter den 
Farbwert für diese LED zurückgibt.

: Bearbeitet durch User
von Forist (Gast)


Lesenswert?

Daniel schrieb:
> Bzw.. Hier mal mein Code..

Was könnte wohl mit dem Hinweis "Längeren Sourcecode nicht im Text 
einfügen, sondern als Dateianhang" gemeint sein?

Schon mal drüber nachgedacht?

von Forist (Gast)


Lesenswert?

Daniel schrieb:
> Ok. Dann lade ich das nochmal hoch...

Das könnte man auch mit einem einzigen ZIP-Archiv lösen

von Joachim B. (jar)


Lesenswert?

Forist schrieb:
> Das könnte man auch mit einem einzigen ZIP-Archiv lösen

900ss D. schrieb:
> Weshalb tar und nicht die einzelnen Dateien? Es machen sich wie die
> Mühe, ein test runterzuladen und zu entpacken anstatt direkt den Code
> anzusehen. Dafür müssten die Dateien aber eben direkt angehängt sein.

ich korrigiere mal:

Es machen sich nicht viele die Mühe, ein Zip runterzuladen und zu 
entpacken anstatt direkt den Code anzusehen.

abgesehen von den Fehlern hat 900ss D. Recht!
Egal wie mans macht ist eh verkehrt wenn Nörgler nörgeln wollen.

von Falk B. (falk)


Lesenswert?

Daniel schrieb:
> Hier dann mal der Code

Naja, du hast dir ja schon genügend Rüffel abgeholt. Wenn man dein 
channels.c überfliegt, sieht das komisch aus. Wirst du für Codezeilen 
bezahlt? Das kann man alles DEUTLICH kompakter schreiben, das ist dann 
auch besser lesbar und verständlicher.

Die Variablen PWM_CH1_IS bis  PWM_CH32_IS sind Käse, das macht man über 
ein Array  PWM_CH_IS[32].

Deine Funktion channels_update ist auch ziemlicher Unsinn, wo mit 
Fleißarbeit im Tippen ein schlechtes Konzept verdeckt werden soll.

Die Funktion channels_run ist eine noch größere Katastrophe. Auch hier 
fehlt die sinnvolle Verwendung von Schleifen und Arrays.

Alles in allem ein ziemlich naiver Ansatz.
1
void channels_run(void) {
2
  int i;
3
4
  for(i=0; i<32; i++) {
5
 
6
    if (PWM_CH_IS[i] != pwm[i][0]) {
7
      if ( ( sysTimer % (get_pwmmode_speed(runmode, i) * TIMERFREQ) ) == 0) {
8
        if (get_pwmmode_changemode(runmode, i) == PWMCHANGESOFT) {
9
          if (PWM_CH_IS[i] > pwm[i][0]) {
10
            PWM_CH_IS[i]--;
11
          } else {
12
            PWM_CH_IS[i]++;
13
          }
14
        } else {
15
          PWM_CH_IS[i] = pwm[i][0];
16
        }
17
      }
18
    }
19
  }
20
21
  RUNPWM = 0;  
22
}

von 900ss (900ss)


Lesenswert?

Falk B. schrieb:
> Alles in allem ein ziemlich naiver Ansatz.

Na ja, was erwartet du? Alle fangen mal an. Wenn es erstmal läuft, kann 
er sich an Verbesserungen/Optimierung machen.

von Daniel D. (daniel_duesentrieb)


Lesenswert?

900ss D. schrieb:
> Falk B. schrieb:
>> Alles in allem ein ziemlich naiver Ansatz.
>
> Na ja, was erwartet du? Alle fangen mal an. Wenn es erstmal läuft, kann
> er sich an Verbesserungen/Optimierung machen.

Danke.. So sehe ich das auch...

Ich muss allerdings auch dazu sagen... Ich habe angefangen den Code zu 
schreiben... Da kam ich nicht darauf... Schleifen mit Arrays zu 
nutzen...

Wenn man sich aber nun den gesamten Code anschaut... sieht man das ich.. 
je weiter ich mit dem Code kam... auch teilweise arrays und schleifen 
einsetze...

So schrieb ich zwar anfangs elend langen Code... Copy&Paste sowie Search 
and Replace... bzw habe mir dann einfach ein php script geschrieben 
welches mir als Output den Code gibt...

Ab durch ne for und schon hatte ich 1000 Zeilen...

wenn man jedoch dann auf pwmmode[][][][]... schaut.. nutze ich da ja 
dann doch schon ein "großes" array.. und die werte von dort übernehme 
ich ja auch in einer for...

alles in allem kann man da sicherlich noch das ein oder andere 
anpassen... aber das kann man ja dann optimieren...

Da der ein oder andere den Code ja jetzt schon vermutlich ein wenig 
kennt...

Frage ich direkt nochmal...

ich habe das array
1
pwm[i][0]

in den channels.c wie man oben sieht.. wird alle TIMER_FREQ (10ms 
default) die pwm "aktualisiert".. also geprüft ob sich werte geändert 
haben.. und wenn.. je nach "speed" und "changemode" (dim oder "hard") 
aktualisiert...

wenn man nun also z.b. den
1
runmode
 ändert wird werden die modedaten der modenummer in
1
pwm[][]
 geschrieben...

die pwm aktualisiert das dann wie oben jede TIMER_FREQ..

ok...

also brauche ich doch jetzt nur z.b. runmode 8 als "funktionsmode" 
nutzen.. und dann eine funktion die die werte in den array
1
pwmmode[8][CHNUM][0]
 "ständig" bearbeitet.. oder?

Die funktion würde z.b. alle 100ms die daten ändern... dadurch das die 
pwm alle TIMER_FREQ (10ms) aktalisiert.. sollte sich das ganze dann 
"live" ändern.. korrekt?

wenn ich also eine funktion schreibe.. die z.b. alle 200ms den 
"nächsten" channel auf 200 stellt von 1 - 32...

würde alle 200ms von 1 - 32 nach und nach mit einem 200ms versatz 
aufdimmen...

korrekt?

mit nem delay als beispiel
1
for (int i=0; i<32;i++) {
2
  pwmmode[8][i][0] = 200;
3
  _delay_ms(200);
4
}

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Daniel D. schrieb:
> So schrieb ich zwar anfangs elend langen Code... Copy&Paste sowie Search
> and Replace... bzw habe mir dann einfach ein php script geschrieben
> welches mir als Output den Code gibt...

OMG!

> Ab durch ne for und schon hatte ich 1000 Zeilen...
>
> wenn man jedoch dann auf pwmmode[][][][]... schaut.. nutze ich da ja
> dann doch schon ein "großes" array.. und die werte von dort übernehme
> ich ja auch in einer for...
>
> alles in allem kann man da sicherlich noch das ein oder andere
> anpassen... aber das kann man ja dann optimieren...

Unfug. Hier geht es gar nicht ums Optimieren sondern um ein paar 
sinnvolle Konzepte und Grundlagen. Aber wenn du so programmierst wie du 
hier schreibst, wundert mich gar nichts. Versuchs mal ohne Red Bull . . 
.

> ich habe das arraypwm[i][0]

Mag sein. Welche Information steht dort drin?

> in den channels.c wie man oben sieht.. wird alle TIMER_FREQ (10ms
> default) die pwm "aktualisiert"

Nö, das sieht man gar nicht, denn diese Zeile
1
 if ( ( sysTimer % (get_pwmmode_speed(runmode, CH1) * TIMERFREQ) ) == 0) {

ist nicht so einfach selbsterklärend. Aber auch hier darf man dein 
"Konzept" arg in Frage stellen. Allein schon die Modulooperation ist 
eher Unsinn. Wenn man einen Timer benutzt, kann man eine Funktion 
periodisch aufrufen. Dann braucht man nur noch einen Zähler, um zu 
wissen, wie spät es ist. Da muss rein gar nichts multipliziert oder gar 
dividiert werden.

.. also geprüft ob sich werte geändert
> haben.. und wenn.. je nach "speed" und "changemode" (dim oder "hard")
> aktualisiert...

Kauderwelsch.

>
> wenn man nun also z.b. denrunmode
>  ändert wird werden die modedaten der modenummer inpwm[][]
>  geschrieben...

Wird nicht besser.

> die pwm aktualisiert das dann wie oben jede TIMER_FREQ..

Mann O Mann.

>
> ok...
>
> also brauche ich doch jetzt nur z.b. runmode 8 als "funktionsmode"
> nutzen.. und dann eine funktion die die werte in den
> arraypwmmode[8][CHNUM][0]
>  "ständig" bearbeitet.. oder?

Wirr deiner Worte Sinn gar ist.

>
> Die funktion würde z.b. alle 100ms die daten ändern... dadurch das die
> pwm alle TIMER_FREQ (10ms) aktalisiert.. sollte sich das ganze dann
> "live" ändern.. korrekt?

Es wird nicht besser.

> wenn ich also eine funktion schreibe.. die z.b. alle 200ms den
> "nächsten" channel auf 200 stellt von 1 - 32...
>
> würde alle 200ms von 1 - 32 nach und nach mit einem 200ms versatz
> aufdimmen...
>
> korrekt?

Vielleicht, aber deine Sprache ist grausam.

> mit nem delay als beispiel
> for (int i=0; i<32;i++) {
>   pwmmode[8][i][0] = 200;
>   _delay_ms(200);
> }

Das kann man als einfachen Test so machen, aber dann ist deine CPU zu 
100% mit diesem Dimmen beschäftigt. Genauer, sie ist zu 99% mit WARTEN 
(delay) beschäftigt! Das ist nur für SEHR einfache Programme oder einen 
Test sinnvoll. Wenn man es richtig machen will, dann nutzt man 
Multitasking. Lies den Artikel und lerne.

Und was deine PWM etc. angeht, kann man das alles DEUTLICH einfacher 
BESCHREIBEN und auch umsetzen.

1.) Man braucht eine PWM, hier als Soft-PWM, welche Daten periodisch 
aus einem Array an Pins ausgibt. Diese läuft mit einem Timer mit relativ 
kurzer Periodendauer.

2.) Man braucht Funktionen, welche die PWM Daten je nach Bedarf und 
Wunsch Ändern, sprich, wenn man eine lineare Dimmung in Zeit X haben 
will, müssen die Daten schrittweise innerhalb der Zeit X verändert 
werden. Wenn man das nicht blockierend machen will, weil eben die CPU 
noch das Eine oder Andere machen soll, braucht man eine Statemachine 
und Multitasking.

Das ist alles nicht sonderlich kompliziert, wenn man das Konzept erstmal 
verstanden hat. Aber dazu muss man schon ein paar gescheite Grundlagen 
bezüglich Programmierung kennen, u.a. Schleifen. Und nicht hyperaktive 
irgendwelchen wilden, aufgedunsenen Code produzieren. In der Ruhe liegt 
die Kraft.

von Daniel D. (daniel_duesentrieb)


Lesenswert?

Falk B. schrieb:
> In der Ruhe liegt
> die Kraft.

Ja.. und im lesen und verstehen auch...

egal...

logischerweise mach ich das mit meinem timer0 als "zeitbasis"... steht 
auch weiter oben....

und doch... ich brauche diese modulo...

und das war nur ein exmaple... die pwm arbeitet ganz von alleine und 
unabhängig.. naja.. verstehen "profis" ja nicht... egal....

Aber.. ja.. Was soll ich DIR sagen... bist ja nen PROFI... ;)

von Daniel D. (daniel_duesentrieb)


Lesenswert?

Aber weisst du... Entweder willst du helfen ala helfen... oder du lässt 
es...

Ich könnte auch nem Profi 24/7 nerven.. Ich will was lernen.. aber mit 
solchen Sprüchen und aussagen wie von dir... da kannste es auch direkt 
sein lassen...

https://github.com/pihome-dev

Mein RePo...

Da ist auch der 32CH Code... schau mal.. wer den Code für eines meiner 
Boards geschrieben hat... (pwmboard) ja auch nen Profi... Multitasking, 
Threading wat auch immer... aber...

Der Herr ERKLÄRT auch mal.. wie auf 900ss auch und mekkert und mosert 
nicht nur...

Also... nicht böse gemeint.. aber bitte... "hilf" oder "lass" es...

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Liest sich ja aehnlich, wie die hier dargestellte Problematik:

https://www.youtube.com/watch?v=QJEc6FPp6Ok

SCNR,
WK

von Peter D. (peda)


Lesenswert?

Daniel D. schrieb:
> und doch... ich brauche diese modulo...

Modulo ist so ziemlich das Teuerste auf einer CPU ohne Hardwaredivision.
Du verschwendest damit CPU-Zeit. Und das kann man bei einer SW-PWM am 
wenigsten gebrauchen.

Oft kann man Modulo durch eine einfache Zählvariable ersetzen, die man 
am Endwert wieder auf 0 setzt. Das ist dann sauschnell.

von Stefan (Gast)


Angehängte Dateien:

Lesenswert?

Daniel schrieb:
> Danke...
>
> Also der Code ist sehr hoch... Da verstehe ich nicht wirklich viel
> von...
Ich hab mal die C-Profis von godbolt.org/CompilerExplorer gefragt: die 
üblichen C-Compiler verstehen von dem Code auch nicht wirklich viel, was 
sicher auch an meinem Code liegt ;-)
Meine Intention war eigentlich ein - bis auf _kleinere_/korrigierbare 
Fehlerchen im C-Abschnitt - lauffähiges Macro-C Plug-in zu posten (asm 
und Compiler workarounds: 'as is') mit dem du als unabhängiger Anwender 
eine 3M bilden kannst, um die These von c-hater:
"Programme" (sprich: Tabellen):"definitiv die beste und universellste 
Variante"
aus unabhängiger Position beurteilen zu können.
In einer Theorie wird vermutet, dass turing-kompatible Sprachen wie C 
die universellste Variante sein könnten und ich glaube, dass C, Basic 
oder asm  für Effekt-Designer, die bereits die Sprache in der 
Systemprogramierng kennen, Macros in der Sprache vertändlicher sein 
können, wenn die Unterschiede zumindest erkennbar sind. Für letzteres 
hab ich mal versucht C-Macros mit ein wenig 'Zucker' aufzuhüschen, 
sodass die einen leichten Basic-touch im Quelltext abgeben.

Disclaimer: Registerdreher u.ä. kann ich erst am WE im Simulatur 
überprüfen, aber das Compilat sieht schon ziemlich plausibel aus.

> Ich könnte auch nem Profi 24/7 nerven.. Ich will was lernen..
Die in der Zwischenzeit bekannt gewordenen Probleme konstruktive Texte 
aus dem Internet auch konstruktiv verarbeiten zu können machen weitere 
konstruktive Vorschläge natürlich schwierig, weil durch die Text-Menge 
an anderen Problemen technische Aussagen kaum zu finden sind. So eine 
Leistungfähigkeit 24/7 ausgabeseitig zu nerven reduziert natürlich die 
Chance eingangsseitig was zu lernen deutlich und erinnert eher eine 
hyperaktive for schleife, die bekanntlich auch viel Leistung hat)

Der erste Punkt den Falk genannt hat ist für das Thema essentiell.
Dein Konzept:
> Also wenn die erste bei 10% ist starte die nächste..
> if (PWM_CH1_IST==10%) PWM_CH1+1_SOLL = max)
ist ohne eine strukturierte/indizierte Zugriffsmöglichkeit auf die 
IST-Werte nicht realsierbar. Unrolling PWM_IS[0]=0; ... PWM_IS[31]=0; um 
ein kleines Projekt auf über 1000 Zeilen zu bringen, lässt sich auch mit 
Indizierten statt Einzelvariablen erreichen und blockiert keine 
technische Umsetzung deines Konzepts.
Am einfachsten wäre es wenn du den naiven Ansatz aus dem großen Projekt 
extrahieren könntest und den ganzen Haufen aus dem php-Experiment 
separat im großen Projekt weiterführst.
1
pwm[channel]  
2
- IST  (is/current)
3
- SOLL (to/destination)
4
- Veränderung 
5
// speed/delta beim Konzept: größere Werte=>schneller; 
6
// delay/divider beim Konzept: größere Werte langsamer  
7
- reserviert(flags/modes: linear/log hard/[mddle?]/soft autoX ... )
8
hübsche Sterne lassen sich am einfachsten mit Abläufen 'im' Kanal blinken
9
void change_hard(wert){ IST=wert; SOLL=wert;}
10
// spart mehr Rechenzeit in der ISR als phy bei der generation von C-Code
gäbe eine konsistente Schnittstelle, um Möglichkeiten im Internet 
konstruktv diskutieren zu können. Für dein großes Projekt passende 
Elemente ließen sich leicht übernehmen, wenn du sowohl eine einfache 
Version als auch dein Großprojekt verstehst.
NB.: ich würde für den Internet-Fork
TIMERFREQ (größer ==> langsameres fading)
in TIMER_MS umbenennen, um allgemein verständlich anzudeuten, dass die 
Konstante die Pause zwischen zwei Aufrufen in (milli)Sekunden und keine 
Frequenz(Hz) meint.

Der andere diskutierte Punkt hat eigentlich nichts mit dem Thema zu tun, 
aber wenn du einen Text mit über 5000 technisch überflüssigen Takten in 
einer ISR in einem Forum veröffentlichst in dem auch Menschen mitlesen 
die den einen oder anderen µC programmiert haben, dann musst du mit 
konstruktiver Kritik an deinem (oder aus unbekannter Quelle kopierten) 
Text rechnen.
So ein Fehlerchen wie ein bequemes modulo passiert schnell und lässt 
sich mit einem externen Code-Audit völlig problemlos korrigieren (falls 
der Verwalter des Quellcodes dabei das Risiko etwas zu lernen in Kauf 
nimmt oder zumindest einen Profi mit der Reperatur beauftragen kann)
[code]
  sysTimer = sysTimer + TIMERFREQ;//TIMER_MS
//sysTimerN= sysTimerN + 1;//sysTimer==sysTimerN*TIMRFREQ
...
   if ( ( sysTimer            % (get_pwmmode_speed(runmode, i) * 
TIMERFREQ)
//  (170T+)*32 == 5400 T
//-if ( ( sysTimerN*TIMERFREQ % (get_pwmmode_speed(runmode, i) * 
TIMERFREQ)
//-if ( ( sysTimerN           % (get_pwmmode_speed(runmode, i) )
// Aufruf 1*sysTimerN
// if (--pwm[i].cnt==0){
//    pwm[i].cnt=pwm[i].delay;
// ~ 10T*32 == 320 T
[/code}
NB.: falls du später einmal log-fading d.h. wie eine Glühbirne mit 
dicker Glühwendel erst zugiges abdunkeln mit laaaangsamen ausglimmen 
implementieren willst, dann lässt sich das beim speed-Konzept(große 
Werte/Differenz:schneller) mit abs(is-soll)*speed implementieren, 
während für abs(is-soll)/delay noch eine Division benötigt wird. Ist mir 
übrigens auch erst bei einem zweiten Versuch ohne Altlast aufgefallen.

Falls du mal eine wilde Verkabelung hast und die 2 Vorrats-mappings in 
der ISR nicht ausreichen, dann braucht jeder Kanal einen zeitintensiven 
Eprom-Zugriff in der ISR, während eine Funktion ch(x) die nur bei 
seltenen Änderungen des Zielwert praktisch im HMI aufgerufen wird selbst 
mit universal Zuordnung weniger Rechenleistung als deine aktuelle 
Variante benötigt.

... und umdenken von typischen C-Abläufen :
Aufruf (Eintrag: warte 5 Sekunden): wartet 5 Sekunden-> nächster Eintrag
in
Aufruf(Eintrag: warte 5 Sekunden): Zeit+ 5 Sekunden merken-->ende
nächster Aufruf                  : gemerkte Zeit nicht errreicht -->ende
nächster Aufruf                  : gemerkte Zeit nicht errreicht -->ende
nächster Aufruf                  : gemerkte Zeit nicht errreicht -->ende
nächster Aufruf                  : gemerkte Zeit nicht errreicht -->ende
nächster Aufruf                  : gemerkte Zeit nicht errreicht -->ende
nächster Aufruf                  : gemerkte Zeit nicht errreicht -->ende
nächster Aufruf                  : gemerkte Zeit nicht errreicht -->ende
nächster Aufruf                  : gemerkte Zeit errreicht --> nächsten 
Eintrag abarbeiten
IST einfach schwierig. Versuch macht kluch.

von c-hater (Gast)


Lesenswert?

Stefan schrieb:

> um die These von c-hater:
> "Programme" (sprich: Tabellen):"definitiv die beste und universellste
> Variante"
> aus unabhängiger Position beurteilen zu können.

Was insofern schwachsinnig ist, als dass du das Konzept nicht verstanden 
hast und Sachen zu beweisen/widerlegen versuchst, die garnicht zur 
Diskussion stehen.

Das Tabellenkonzept verlagert nur die Arbeit der Effekt-Generierung auf 
ein System, was dafür sehr viel besser geeignet ist als ein kleiner µC, 
weil es ein interaktives grafisches GUI mit vernünftigen und 
komfortablen Ein- und Ausgabemöglichkeiten für die Parametrierung und 
und die unverzügliche Beurteilung des Ergebnisses liefern kann. Das 
Ergebnis dieser Arbeit ist dann halt eine Tabelle.

Der µC muss nun bloß noch diese Tabelle abspulen.

von Falk B. (falk)


Lesenswert?

Stefan schrieb:
>> Also der Code ist sehr hoch... Da verstehe ich nicht wirklich viel
>> von...
> Ich hab mal die C-Profis von godbolt.org/CompilerExplorer gefragt: die
> üblichen C-Compiler verstehen von dem Code auch nicht wirklich viel, was
> sicher auch an meinem Code liegt ;-)

Du bist entweder ein Troll oder ein noch größerer Autist als der seelige 
Josef G. Ich tippe auf Letzteres. Mann O Mann, so einen Wahnsinn in 
Quelltextform hab ich noch nicht gesehen. Und alles, um ein paar LEDs 
lustig blinken zu lassen.

von Stefan (Gast)


Lesenswert?

Falk B. schrieb:
> Du bist entweder ein Troll oder ein noch größerer Autist als der seelige
> Josef G.
Dann dürfte Daniel wohl doch Recht gehabt haben wenn bei dir ein 
konstruktives Posting derartig Agressionen auslöst, dass du gezwungen 
bist fremde Menschen als Troll zu bezeichnen.
> Ich tippe auf Letzteres. Mann O Mann, so einen Wahnsinn in
> Quelltextform hab ich noch nicht gesehen.
Funktionsfähige Programme werden bei entsprechender Prägung häufiger als 
Wahnsinn gesehen, weil bei entsprechender Erregung keine Möglichkeit 
besteht Texte lesen zu können.
> Und alles, um ein paar LEDs lustig blinken zu lassen.
Beim langen Quelltext den der Falk-Bot ins Internet gepostet hat reicht 
es halt nicht zum blinken oder anderen lauffähigen Quelltext, sodass dem 
Bot nur Sozialhilfe bleibt.

Kannst du irgendwelche Buchstaben identifizieren die dich derartig 
aufgeregt haben könnten?

von malsehen (Gast)


Lesenswert?

Peter D. schrieb:
> Modulo ist so ziemlich das Teuerste auf einer CPU ohne Hardwaredivision.

?

von Falk B. (falk)


Lesenswert?

malsehen schrieb:
> Peter D. schrieb:
>> Modulo ist so ziemlich das Teuerste auf einer CPU ohne Hardwaredivision.
>
> ?

Er meint, daß eine Modulo-Operation viele Takte benötigt, denn es ist 
der Rest einer Integerdivision. Je nach Zahlenformat und Größe 
vielleicht um die 100 und mehr. Ein einfacher Zähler mit Vergleich 
braucht nur eine handvoll Takte.

von Stefan F. (Gast)


Lesenswert?

Stefan schrieb:
> 2ter_versuch.c

Sorry, aber das ist kein C-Quelltext. Wolltest du damit einen 
Obskurity-Wettbewerb gewinnen? Ich glaube du hast den Sinn der 
Hochsprachen überhaupt nicht verstanden!

Der primäre Sinn einer Programmiersprache liegt darin, für Mensch und 
Maschine lesbar zu sein. Der Sinn einer Hochsprache (wie C) liegt darin, 
für andere Menschen 30 Jahre später immer noch verständlich zu sein.

Deinen Code können andere nur nach massivem Zeiteinsatz verstehen. Es 
wäre wirtschaftlicher, ihn dahin zu werfen, wo er hingehört: In die 
Mülltonne. Und dann alles neu programmieren. Dieser Stil zusammen mit 
deiner Einstellung ist Gift für das Unternehmen. Wenn ich dein Chef 
wäre, würde ich dich nach so einer "Leistung" entlassen. Mir wäre völlig 
egal, ob der Code überhaupt funktioniert.

Falks Reaktion ist absolut angemessen.

Falk B. schrieb:
> so einen Wahnsinn in Quelltextform hab ich noch nicht gesehen.

von Daniel D. (daniel_duesentrieb)


Lesenswert?

Nunja....

Was soll ich hier groß noch sagen!?

Schon lustig.. wie Halbherzig die "Profis" bei der Sache sind...

3000 Zeilen mekkern... aber nicht mal 10 Zeilen für nen Beispiel... Also 
wenn man soviel Zeit zu mekkert hat... aber es nicht zu erklären... 
erklären wollen ... erklären möchte...

stellen sich mir da so einige Fragen...

Wie schonmal geschrieben wurde... Jeder hat mal irgendwie... irgendwo 
angefangen... Hier jedoch hat der ein oder andere das Wissen wohl mit 
einem goldenen Löffel bekommen...

Das wissen... nimmt man dann auch mit ins Grab...

Oder ab... man kann sich gut artikulieren... aber null Coden... Also 
viel stänkern aber wenig erklären/zeigen...

Kritik und Co gehört alles dazu... Wenn man jedoch in einem Forum aktiv 
ist... wo Menschen fragen stellen... und/oder Hilfe suchen...

Sollte man auch schon helfen... und nicht nur mit iwelchen "dummen" 
Aussagen (doofe Aussage das "dummen", aber)...

Der Malerlehrling klebt die Tapete falsch an... der Meister kommt... und 
"zeigt" es einmal... Voila... der Lehrling kann das... Obwohl er das 
Theoretisch schon 30000 mal hatte....

Ich gehöre zu genau so einer Art Mensch...

Man kann mir hier 10000000 mal was sagen... erklären... ich kann es 
10000000 mal lesen... ich kapiere ich NIICHT... Und das seit 33 
Jahren....

Wenn ich es aber gleichzeitig SEHE... kapiere ich es...

Doof gesagt... Ihr könntet mir jetzt noch 30000000mal sagen Strom nicht 
anfassen, das tut weh... Ich würde es trotzdem tuen... um zu sehen ob es 
so ist...

Ich lerne 99% by "learning by doing"... Die anderen 1% sagen mir... 
Netzspannung und "tödliche" Spannungen lassen wir mal sein... Also immer 
Netzteile galvanisch getrennt dazwischen... nur 12 V und eben solche 
Sachen...

Jetzt könnt ihr Profis weiter mekkern... stänkern und was weiss ich 
nicht und euer Wissen mit ins Grab nehmen...

Oder die nette freundlichkeit besitzen... Das Forum so zu gebrauchen wie 
es soll...

und mir netterweise etwas helfen?!

Danke

von Falk B. (falk)


Lesenswert?

Daniel D. schrieb:
> und mir netterweise etwas helfen?!

Sollten wir das? Bei deinem Tonfall? Und deiner "Fähigkeit", Texte zu 
lesen und ggf. zu verstehen?

Beitrag "Re: Wie macht man solche Lichtmodes? Lauflicht, PWM und Co"

In diesem Beitrag sind so komische, blaue Wörter drin. Fahr mal mit 
deiner Maus drüber und drücke die linke Taste, du wirst staunen!

P S Du solltest an deiner passiven Kritikkompetenz arbeiten.

https://de.wikipedia.org/wiki/Kritikkompetenz

von Ste (Gast)


Lesenswert?

Daniel D. schrieb:
> Nunja....
>
> Was soll ich hier groß noch sagen!?
Es wäre höflich wenn du die Frage der Falk-Gruppe beantworten würdest. 
Fragen werden häufig auch von naiven (intelligenten) Menschen dazu 
genutzt, um etwas zu lernen.

> Schon lustig.. wie Halbherzig die "Profis" bei der Sache sind...
"Profis" hängen halt Vollherzig an ihren uralten Sachen:
Beitrag "Re: DMX Steuerung 24 Kanal"
DMX wird sowohl von Profis genutzt, also Menschen die bspw. auf einem 
Konzert im Auftrag ein paar Lampen blinken lassen, als auch von 
Hobbyisten die mit meist kleineren DMX-Anlagen durch die Gegend tingeln. 
Hobbyisten dürfen sich richtig austoben und haben keinerlei Probleme 
sich mit Menschen zu unterhalten die Lichteffekte mit Amason-Geräten 
oder AVR programmieren, weil deren Kunst anders ist als 
Programmierung.
Beim 24 CH DMX-Projekt zeigen sich keinerlei Ambitionen das Projekt zum 
30 CH-DMX hochzuprogramieren, obwohl der AVR noch 7 pins brach liegen 
hat.

Als Kunsthandwerker programmiert ein "Profi" den Knight-Rider-Effekt 
nicht mit einer Statemaschine (wie hier als "Profi" empfohlen), sondern 
mit einer for schleife:
https://www.mikrocontroller.net/attachment/422122/KnightRiderLEDs.zip
und legt auch keinen einzigen Regenbogeneffekt in das zip, um eine 
künstlerische Ambition zu zeigen.
Beitrag "Re: Wie macht man solche Lichtmodes? Lauflicht, PWM und Co"
(es machen sich nicht viele die Mühe, ein Zip runterzuladen)

Wenn in einer Wohnung ein Knight-Rider-Effekt-Gerät gut reinpasst, dann 
eignet sich so ein Gerät auch als Hobby-Projekt, weil es halt schön 
aussieht.

Professionell gestaltete Webseiten versuchen Multithreading mit/ohne 
Arduino (aber beides mit C statt einer Bildungssprache wie Pascal,Basic, 
Modula, MIXAL,,...) zu erklären:
http://stefanfrings.de/multithreading_arduino/

C-Programmierer haben von Adam Dunkels die C-Version der protothreads 
und können dadurch preisgünstig mit einem 8-bit AVR Daten fürs Internet 
produzieren.

> 3000 Zeilen mekkern...
Profis bekommen lt. Freischreiber.de zwischen 1€-10€ je Zeile 
(eigentlich nicht für die Zeilen, sondern für den Aufwand bspw für die 
Wikipedia-Recherche zu ihren Themen). Bei Instagram.com gibt es tw. über 
1000  pro Beitrag .,,,
Altmodische Hobby-Erklärer (die anderen Menschen Tischtennis, Mathe, 
Protothreads oder VBA auch mit Händen und Füßen erklären), bekommen 
allenfalls eine Aufwandsentschädigung (eher im Sinne von Spielgeld).
Bei Künstlern besteht halt das Risiko ähnlich viele Zeilen zu 
produzieren, weil sie auch die Entstehung von "basic meets protothreads" 
(protothreads for beginners) aufarbeiten müssem (und die Einnahme aus 
Vermietung von Knight-Rider-Effekten an ein acid-house)

Falls du mal 3000 Zeilen brauchst die zumindest die wichtigsten Aspekte 
bei der Programmierung eines Regenbogeneffektes erläutern ... kurz 
nachfragen

> aber nicht mal 10 Zeilen für nen Beispiel...
Beitrag "Re: Wie macht man solche Lichtmodes? Lauflicht, PWM und Co"
LUA (ein modernes basic): jeder der nen Beispiel preisgibt offenbart 
praktisch zusammen mit dem Beispiel in welcher Sprache er künstlerisch 
programmiert. Im ANSI/ISO C/C++ Framework müsste ein Künstler (ohne 
protothreads) zugeben, dass er C11 verwendet und stände damit unter dem 
Verdacht ein Profi zu sein der nur Geld verdienen will.

> wenn man soviel Zeit zu mekkert hat...
... dann fehlt Zeit um den ersten Regenbogeneffekt zu programmieren und 
damit Wissen künstlerisch anzuwenden.

> aber es nicht zu erklären...
... erklären könnte man "es" an 48 CH PWM Boards in einigen (ansonsten 
ungenutzten) Gästezimmern:
http://stefanfrings.de/binaeruhr/index.html
Beitrag "Re: Binäruhr mit STM32 Blue Pill Board"
- 32-bit computing ohne OS ist sehr anspruchsvoll, weil praktisch zu 
viel Leistung ohne einfache Schnittstelle bereit steht (ein 80368 ist 
selbst mit 4mb bios schwierig)
- ein Künstler würde nicht in allen Zimmern das gleiche Bild aufhängen, 
sondern würde jeden Raum individuell gestalten d.h. unterschiedliche 
Tapeten, unterschiedliche Lichteffekte, unterschiedliche Uhren etc.
- die PWM-Boards könnten sich über Radio oder Internet selbständig über 
den aktuellen Stand der Uhrzeit informieren, sodass sie als intelligente 
Lichteffekte keine regelmäßige Wartung benötigen.
- die Farbtöne werden handwerklich über die Auswahl von 
Hardware(Vorwiderstände) statt Software  "ausbalanciert"
- vor lauter grübeln wird beim zusammenstellen der Code-Tabelle ein 
Eintrag für die Tastenentprellung vergessen, sodass beide Boards beim 
umschalten von Uhrzeit auf Weckzeit unkontrolliert flackern ("es sei 
denn es ist gerade zufällig 00:00 Uhr")
- ein bisschen Mut, um mit einem der Boards mal ein paar Nächte 
gemeinsam zu verbringen, scheint dem Hersteller zu fehlen
- stilistisch (von den 'ausbalancierten' Farben und dem Gehäuse) wäre es 
mMn. passender die Objekte in ungenutzten Kinderzimmern aufzustellen (in 
denen Gäste im Notfall auch übernachten könnten)
==> die Lichteffekte mekkern im Dämmerlicht ruhebedürftige Gäste an, 
weil sie nicht höflich ihre Strahlungsleistung reduzieren
Ein Profi produziert auf Anhieb eine Kleinserie, um Entwicklungskosten 
zu sparen.
Mit dem Board und den LED ließen sich - wenn Bedarf an Kunst bestünde - 
auch Regenbogeneffekte  programmieren.

Mit dem Projekt
Beitrag "IRMP - Infrared Multi Protocol Decoder"
steht eine Riesenauswahl an entprellten Tasten (+Riesenauswahl an µC) 
zum softwareseitigen ausbalancieren von Farben etc. bereit


Ganz anders wenn ein Projekt für Gäste programmiert wird:
Beitrag "Re: LED-Gesellschaftspiel "Light Touch""
- ein vorgeblicher Google-Insider mekkert, dass ein Künstler in seiner 
Firma keine 2 Wochen überleben würde ("alles Anfängerfehler")
- der - vermutlich inoffizielle - Google-Insider besäuft sich im 
Internet wie ein Beisitzer vom Stammtisch.
- der Künstler gibt im Interview preis, dass er intern auch eine 
Bildungssprache verwendet (Pascal ist praktisch 'ne ordnungsbewusste 
Variante von Basic)
- "Die Software enthält eine Statemachine," d.h. selbst mit wenigen 
Statemachines lassen sich anspruchsvolle Projekte künstlerisch 
programmieren, wenn das Konzept stimmig ist.
Keine Serie, sondern pro Haushalt ein Exemplar (wenn ich nicht zu faul 
wäre u.a. für mich)

Möglichkeiten für Bildungsprachen gäbe es auch bei µC.net:
Beitrag "Re: MINOS - Minos Is No Operating System"
- ein Temperament entdeckt die versteckte Bildungssprache:NIC und 
mekkert natürlich ...

Kunst kann sich auch im wahnsinnigen Programmieraufwand zeigen, nur um 
ein paar LED lustig blinken zu lassen:
Beitrag "Re: "LED-Spectrumanalyzer"software ohne Fouriertransformation"
- einem hiesigen SD-card-Player scheint "Asm is better.."
- der Künstler berichtet:"DSP fuer Arme " d.h. berücksichtigt finanziell 
schlechter gestellte Kunstliebhaber, die sich für ein paar LED nicht 
gleich einen FPGA kaufen wollen

oder einen Webserver in der Künstlersprache MIXAL bzw. AVR-ASM:
Beitrag "Webserver Ethernet ENC28j60 ATmega1284p TCP ARP Assembler"
- kein Profi würde MIXAL/ASM zur Programmierung eines Webservers 
verwenden ==> definitiv Kunst

==> C _kann_/könnte als Hochsprache verwendet werden, aber ohne 
Erfahrung mit einer Anwendungssprache + Treibersprache, etlichen 
gescheiterten Projekten oder sehr sehr viel arbeit, ist es - zumindest 
nach meiner Erfahrung - praktisch unmöglich.

> erklären wollen ... erklären möchte...
wirklich erklären möchte das wohl kaum jemand

> stellen sich mir da so einige Fragen...
>
> Wie schonmal geschrieben wurde... Jeder hat mal irgendwie... irgendwo
> angefangen...
... und programmiert schnell eine SODA-PWM (bspw. beim Umstieg auf 
Ardinio-OS ), sodass man zum Manager aufsteigt:
https://de.wikipedia.org/wiki/Investitionsruine
https://de.wikipedia.org/wiki/Versunkene_Kosten
.. und deren typischen Probleme hat. Bei solchen versunkenen Kosten 
besteht das größte Riikio darin die Kosten nicht abschreiben zu können 
und lieber zu mekkern

> Hier jedoch hat der ein oder andere das Wissen wohl mit
> einem goldenen Löffel bekommen...
... so ein goldener Löffel nannte sich früher noch etwas profaner:
https://de.wikipedia.org/wiki/Buch
d.h. früher hat man direkt mit dem Speichermedium gelernt während ein 
moderner Pädagoge wieder altmodische Erziehung ("Ohren lang ziehen") von 
einem einheimischen Buchautor fordert:
Beitrag "Re: Analogwert im zweierkomplement seriel senden?"
Solche Didakten vermarkten sogar Fernbedienungen ohne Bildungssprache 
als "lernbetty". Immerhin kann die Betty digital mekkern (SprachAUSgabe 
ist vorprogrammiert).

Ich hab das Protokoll aus dem µC.net Projekt mal zur Probe auf einem 31 
CH PWM-Modul (mega16) installiert und dabei festgestellt, dass es 
perfekt in die Interrupttabelle passt.
Aus Künstler-perspektive:
- Interrupttabelle; 100% sauber nach den Regeln der Kunst 0 
Goto/Jmp/rjmp/ijmp
- den Sprung aus der Interrupttabelle übernimmt der allereinfachste 
timer 0
- keine C übliche Diskriminierung in gut <god interrupt> und schlecht 
<bad interrupt>
(ein Künstler würde <bad interrupt> in <unused interrupt> umbenennen, um 
nicht unnötig abzuwerten)
- Compiler produzieren ähnliche Quelltextmonster wie du und betreiben - 
häufig technisch unnötiges- unrolling, wodurch der Quelltext noch 
länger wird
- C kennt lediglich ein "if". Mit macros lassen sich bis zu 16 if_, _if, 
If,... gestalten, sodass ein Autor viel mehr Möglichkeiten hat sich 
differenziert auszudrücken

'literate programming' stammt aus dem Buchdruck(TeX).
"The Art of Computer Programming": MIX-Assembler-Language (fast 
AVR-Assembler-Language)
Für Profis ist MIXAL völlig wertlos, weil man damit nicht billig 
programmieren kann.

Ein Lichteffekt (in C-Script auf dem µC)
Beitrag "Re: Atmega8A UART sendet nur Müll"
wird bspw. eingesetzt, um Fehler bei dem Protokoll zu suchen

ohne Erfahrung mit Lichteffekten zur Messung wird teure 8 CH Hardware 
vor dem helfen verlangt:
Beitrag "Re: Atmega8A UART sendet nur Müll"
häufiges mekkern kann halt dazu führen eine einpolige Leitung mit 8 
Kanal-Geräten messen zu müssen

Und wenn der Chef vorher mit einer fristlosen Entlassung gedroht hat, 
falls der Angestellte das Protokoll implementiert, dann wird sogar eine 
verdoppelung der TXD-Leitungen empfohlen:
Beitrag "Re: Atmega8A UART sendet nur Müll"
(gerade zusätzliche Leitungen veringern die Chance den Fehler in der 
ersten Leitung zu finden)

==> Erfahrung mit dem timing von Lichteffekten kann wirklich  helfen 
teure Hardware und fehlerträchtige Leitungen zu sparen

> Das wissen... nimmt man dann auch mit ins Grab...
Nein. Das für Lichteffekte erfahrungsgemäß relevante Wissen über 
protothreads, PWM/BAM/PDM/... floatingpoint, serielle Datenübertragung 
DMX/MIDI/etc.  etc. liegt häufig outgesourced in Projekten auf Servern 
im Internet d.h. das Wissen ist nicht im aktiven Bereich und muss 
fehleranfällig verlinkt werden d.h. keine Chance Beispielcode in den 
ganzen Links zu finden.

"Profis" verfallen bei diesem Thema über Monate/Jahre in einen 
energiesparenden sleep-mode d.h. die haben 0 Interesse am Thema und 
sobald sich jemand für das Thema interessiert explodiert erfahrungsgemäß 
der Thread:
Beitrag "Re: Knight Rider Schaltung"

Die problematische passive_ Kritikompetenz wird praktisch durch _jeden 
Hobbyisten, der sich für das Thema interessiert und bereits mehr als 24 
CH programmiert hat, herausgefordert. Viele schaffen es einfach nicht 
ihre Tastatur zu beherrschen, wenn sie KEIN Interesse haben.

> Oder ab... man kann sich gut artikulieren... aber null Coden...
Coden ist sehr selten ein Problem:
Beitrag "Re: Minimalistisches kooperatives Multitasking."
es fehlt häufiger Erfahrung wie man mit 5000 loops pro sekunde auch 50 
Effekte @ 100HZ organisiert.

> Also viel stänkern aber wenig erklären/zeigen...
Zum erklären/zeigen der Protothreads müsste man eigentlich eine 
interaktive APP schreiben. Traditionelle Hobby-Erklärer können sowas 
nicht, weil sie direkte Gespräche und herumfuchteln mit den Armen u.ä. 
gelernt haben.

> Kritik und Co gehört alles dazu... Wenn man jedoch in einem Forum aktiv
> ist... wo Menschen fragen stellen... und/oder Hilfe suchen...
... dann mekkern die Nachbarn aus dem Forum "Ausbildung und Beruf", weil 
Hobbyisten ohne Aussicht auf Profit schöner /abwechslungsreicher 
programmieren dürfen.  'literate programming' wird nirgends bezahlt.

> Sollte man auch schon helfen... und nicht nur mit iwelchen "dummen"
> Aussagen (doofe Aussage das "dummen", aber)...
die dummen Aussagen werden im Profi-Forum "Ausbildung und Beruf" 
unterrichtet d.h. lernwillige, die automatisch sowohl die 
unkommerziellen als auch die profitorientierten Beiträge lesen, lernen 
dort automatisch die "dummen" Aussagen

> Der Malerlehrling klebt die Tapete falsch an... der Meister kommt... und
> "zeigt" es einmal... Voila... der Lehrling kann das...
Maler(auf Leinwand) und Maler(auf Rigips) sind völlig andere Berufe bzw. 
Berufungen.
Ich hab mal im horrorhaus_hamburg gewohnt, als es kurz außerhalb von 
Hamburg war.
- meine WG hat den Dachboden erwischt d.h. wir durften 'nur' wie beim 
Knight-Rider-Effekt-Gerät am (Strobo)Poti drehen, um den vom Vermieter 
gestellten Effekt für Gäste zu optimieren
- trotz der eher einfachen Programmierung bzw. Parametrisierung dürfte 
es eine halbe Stunde gedauert haben bis wir die - unserer Meinung nach - 
optimale Einstellung gefunden haben
==> in den unteren Räumen gab's nur Angst für's Eintrittsgeld... bei uns 
gab es richtige Panik!!

Stilistisch dürftest du einen etwas anderen Wohnstil haben, aber von der 
Programmiertechnik ist es praktisch überall im künstlerischen Bereich 
ähnlich:
- für einfache Strobo/Knight-Rider-Effekte reicht eine for schleife
- ansonsten mehrere Schleifen und Impulstabellen(Noten) kombinieren
- tw. ist es einfacher bspw. 18 Flackereffekte im Baumarkt einzukaufen 
--- 4 davon behalten und diese im Ensemble mit 4 Analogausgängen in der 
Helligkeit zu programmieren
- richtig schwierig ist es vor allem die passenden Parameter - meist 
experimentell - herauszufinden.
NB.: 12 der 18 Effekt-Geräte waren soziologisch höchst interessant: der 
Baumarkt hat es wirklich ernst gemacht mit dem kleinen Preis und hat 
2,49 gaaaanz klein unter das Exponat geklebt, sodass die ganzen 
Schnäpchenjäger eine Woche lang stumpf daran vorbeigerannt sind.


> Obwohl er das Theoretisch schon 30000 mal hatte....
> Ich gehöre zu genau so einer Art Mensch...
ich gehöre zu so einer Art Mensch die aus reiner Bequemlichkeit lieber 
mit Sesseln durch die Gegend läuft, anstatt sich völlig unnötig im 
Fitnessstudio zu quälen.
Wenn ich mal ein paar Tage auf einen Hund aufpasse, dann benehmen die 
sich praktisch automatisch innerhalb kürzester Zeit kulturell orientiert 
d.h. die finden innerhalb der ersten 12 Stunden ihren ersten Einbrecher, 
können Geräusche nicht nur nach Lautstärke beurteilen, sondern sind bei 
guter Musik näher an den Boxen als ich und versuchen bei einem 
(subjektiv) schlechten Knalleffekt verzweifelt in das nächstbeste Zelt 
einzubrechen.
Als ich einmal zu lange beim einkaufen getrödelt hab hat mein Hund eine 
echte Profi von werder.de angequatsch, sodass ich mich unaufällig nach 
dem Einkommen der Profis erkundigen konnte: ca.10K€/Monat. Was genau 
blogging über Propellerhead/FPGA/STM-32 oder Thermomix bringt bleibt 
natürlich Geheimnis der "Profis"

Der Hund konnte sogar Fluchtkunst d.h. man konnte den erst mit in die 
Sauna nehmen und dann ist der - passend zum Projekt - geflüchtet. Als 
ein zufällig vorbei radelnder Burning-Man-Programmierer sich kurz 
aufwärmen wollte und etwas verwundert war warum ein Hund vor der 
Saunatür sitz konnte man dem trocken erklären: 'this dog is no Hot-Dog. 
she don't like to come in' (Disclaimer: etwas konstruiert: irgendwie 
ging es eher um die Organisation der dortigen Veranstaltung d.h. die 
programmieren schon eine Woche vor dem offiziellen Termin drauflos)
==> mit etwas Gespür findet man richtige Experten, weil man zufällig am 
gleichen Ort sitz.

Und in der hiesigen Beitragspause zum Thema habe ich jetzt noch eine 
Bekannte des Hundes wiedergetroffen die mittlerweile im 
Amason-Controlling jobbt d.h. die organisieren da Support,Reparatur  und 
Entsorgung von Unterhaltungselektronik --- haben in der Wohnung zig von 
den Amason-Effektgeräten rumstehen ---  können (von der Menge her) 
besser Lichteffekte programmieren als ich ......uuuuund: wollen im 
Winter (neben dem typischen Finanz-Mathe-Problem) zumindest löten und 
bisschen AVR-Programmierung zur Probe lernen.
==> selbst gute Programmierer kommerzieller Effekte interessieren sich 
für Selbstbau, weil so etwas anders ist (nicht besser)


> Man kann mir hier 10000000 mal was sagen... erklären... ich kann es
> 10000000 mal lesen... ich kapiere ich NIICHT... Und das seit 33
> Jahren....
Seit ca. 3 Jahren versuche ich immer wieder die Protothreads zu 
verstehen, weil die manchmal bei µc.net stefanfrings.de wikipedia.de 
etc. erwähnt werden. Ich hab sie definitiv NIICHT kapiert, obwohl ich 
sie mehrmals gesehen hab.
In so einem schweren Fall ist es einfacher die Dinger selbst zu 
erfinden: dann hat man sie zwar immer noch nicht in C verstanden, kann 
sie aber - zumindest theoretisch - trotzdem erklären.
(oben fehlte noch eine lauffähige Implementation und ein passender 
Titel)

> Wenn ich es aber gleichzeitig SEHE... kapiere ich es...
https://wokwi.com/arduino/projects/306850093217088064
"basic meets protothreads" in Anlehnung an das µC.net Projekt "LabVIEW 
meets µC" (dt. Labor-Anzeige mit µC)
- 2 Effekte gleichzeitig SEHEN
- in der aktuellen Programmierung bis zu 8 gleichzeitig SEHEN
- Array statt pointer: begrenzte fexibilät, aber häufig einfacher zu 
lesen
- eine Art basic (+nuance von ASM) wie es viele Management-Studenten 
lernen (die verwenden hier in der Gegend VBA und helfen damit direkt den 
Portokassen von älteren Basics)
- von hier aus läuft der mega nur mit ca.1 MHZ +-40%, sodass das timing 
ziemlich aus dem Ruder läuft
- falls du mal C lernen willst, um auch wie die "Profis" 
AVR-ethernet-module programmieren zu können, dann kann ein Beispiel in 
basic den Einstieg erleichtern.
- eine unvorbereite Übersetzung von MIXAL/ASM nach Arduino braucht 
viele Wochen d.h. wenn man technische Hilfe von MIXAL-Anhängern 
braucht, dann kann das wg. der Einarbeitung etwas länger dauern
- ("Profi"): "mehr eine Idee als eine praktische Lösung" d.h. Herr 
Dunkels kann einige seiner  C-Leser auch nicht davon überzeugen, dass so 
etwas praktisch eine Lösung sein kann.
- generell: bei Erweiterungen mit Makros sind (verständliche) 
Fehlermeldungen sehr sehr schwierig d.h. wenn man nach jedem kurzen 
Abschnitt kurz compiliert hat man ungefähr eine Ahnung wo der Fehler 
sein muss, ansonsten wird die Suche kompliziert.

> Doof gesagt... Ihr könntet mir jetzt noch 30000000mal sagen Strom nicht
> anfassen, das tut weh...
solange du nicht im Verein der Elektriker bist, darfst du das sogar 
(prinzipiell). Allerdings haben viele der Vorschriften auch schlechte 
Erfahrungen mit Strom als Grundlage.

> Ich würde es trotzdem tuen... um zu sehen ob es so ist...
im Zweifelsfall im hell erleuchteten Raum um Mitternacht (mit FI) 
ausprobieren (vor dem Experiment natürlich alle Taschenlampen etc. 
sorgfältig verschließen und kurz vergessen was du vorhast): praktisch 
siehst du nicht ob es so ist, aber der Schrecken über den Stromausfall 
um Mitternacht bleibt in Erinnerung.

> Ich lerne 99% by "learning by doing"...
"by doing": sammelt man Erfahrungen, trainiert korrekte Einrückungen, 
geradeaus tapezieren je nach Stilrichtung etc.
- Als Künstler lernt man FI-Steckdosen an einem THW-Anhänger als 
hypersensibel kennen und kämpft wie ein Elektriker um möglichst hohe 
Einschaltquoten d.h. man sucht bei Unwetter ob die Pommes-Bude evtl. 
etwas Wasser an eine Leitung abgibt, nur halt aus anderer Perspektive.
- Sobald man den ersten Meister vom historischen Erhalt von roten 
Leitungen in alten Kasernen überzeugt hat gewinnt man ein gewisses 
Selbstvertrauen bzgl. 230V/400V Kompetenz und erklärt später E-Azubis 
Messungen/Prüfprotokolle während man den Profis beim Hallensport 
(schwere einpolige Leitungen) zuschaut (in dem Fall wusste der 
verantwortliche Elektromeister von seiner aktiven Kompetenz d.h. so 
ein Meister hat aktiv i.A. die Organisation seiner Firma im Kopf und 
freut sich - im Rahmen der Alternativen- wenn er vor Ort nur körperlich 
arbeiten muss. Einem Meister fällt auch kein Zacken aus der Krone wenn 
ein Hobby-Elektriker Azubis was über Strom erklärt - Hobby-Elektriker 
und Azubis sind auch relativ kompatibel in Gesprächen, weil man eher 
selten als Oberlehrer wirkt und die komischen Messgeräte selbst nicht 
kennt)
- Rucksäcke mit einem tiny-AVR drin können schon mit 12V anfangen zu 
brennen, wenn man nicht gaaaaanz sorgfältig isoliert
- Als Künstler hat man manchmal ein paar LED mit Notstromversorgung im 
Rucksack d.h. wenn auf einer kleinen Veranstaltung das Benzin ausgeht 
hängt man fürsorglich ein paar LED in den Baum ... und wird nachdem 
genug Benzin vorhanden ist angemekkert die LED würden blenden (objektiv 
schon korrekt, aber eher ungünstiges timing)
- Wenn man erst bequem einen IR-sensor zum Empfang von 
Fernbedienungtasten direkt an die rs232 anschließt und aufgrund von zu 
vielen PC-Abstürzen bei Sonnenschein das Empfangsprogramm vom PC auf 
einen µC transferiert, dann lernt man unleserlichen Quelltext von früher 
kennen.
- Man lernt den subtilen Unterschied zwischen Kunsthandwerk und Unfall 
bei der Bearbeitung von Sicherheitsglas mit dem Glasschneider kennen: 
das Effektglas, das bei so einer Bearbeitung überraschend entsteht, kann 
man mit einem Notfallhammer auch  - sogar einfacher - im Kunsthandwerk 
erzeugen
- Wenn man vorher geholfen hat die Innenstadt mit Heatball basierten 
Lichteffekten auszustatten, dann kann man später einem Anwohner erklären 
warum dort Geräte besonders häufig kurz vor Weihnachten ausgefallen 
sind (die Effekte hätten auf die centi-sekunde genau programmiert werden 
müssen, um den Sternpunkt im vertraglichen Bereich zu halten)
- Als AVR-Hobby-Programmierer (u.a.: bunte kleine Türme) kann man 
sogar ehemalige Profi-PIC-Programmierer (u.a: bunte große 
Fernsehtürme) kennenlernen (die hatten noch 'nen größeren Posten blauer 
und weißer LED mit Platine/Kühlköper aus gescheiterten Projekten 
rumliegen, die hervorragend zur Deckendekoration von kleinen Hallen 
passen würden ... )
... usw.

===> Lichteffekte + digitale Elektronik (inkl. Zubehör) können sehr sehr 
vielseitig sein und viele Stakeholder haben.
Ein richtiger Meister muss nicht mekkern, weil er selbst Ahnung vom 
Thema hat

... ich hab schon einige Ausstellungen besucht und mit actionscript, 
basic-stamp, pascal, SPS, asm, analog bis zu C++(interaktive 
Tischinstallation mit aufwändiger Grafik) relativ viel geshen, aber C 
...... C passt vom Stil - zumindet nach meinem Eindruck - nicht zu 
Kunst.

> Die anderen 1% sagen mir...
für die anderen 1% sind die gelangweilten Profis aus "Ausbildung und 
Beruf" zuständig.

> Netzspannung und "tödliche" Spannungen lassen wir mal sein..
> Netzteile galvanisch getrennt dazwischen... nur 12 V und eben solche
> Sachen...
ich hab mit einer sehr bunten Mischung aus Spannungen angefangen d.h. 
Hochspannung aus dem experimentellen Ionisator konnte bequem 
230V-Schalter überspringen und so hochempfindliche Lichtorgeln 
verunsichern. Damals war man noch etwas naiver d.h. man hat Leitungen 
vorsichtig(!) mit den Finger getestet ohne gleich vom FI erschreckt zu 
werden.
Es gab Gerüchte über sadische Methoden bei den Profis im Röntgenbereich 
d.h. dort wurden wohl Lehrlinge mit aufgeladenen Kondensatoren beworfen, 
sodass diese Scherzen bekamen sobald sie erfolgreich einen fangen 
konnten.
Mit etwas Folie aus dem Erste-Hilfe-Kursus ließen sich noch richtige 
Blitze mit dem Finger aus dem Bildschirm zaubern.

Als biologisch älterer Mensch darf man das natürlich nicht empfehlen: 
also NICHT anfassen

... und vor allem hatte ich wirklich goldene Löffel:
Ein 8-bit Entwicklungssystem für ca. 5000$  d.h. TV, C64, 
Wechselfestplatte und BÜCHER.
Wenn man sich für das Thema Lichteffekte interessiert konnte man damals 
nach ca. 5 Jahren:

(+2):in die DDR exportierte Lichtorgeln:
- elektronisch Kopien der Profi-Geräte vom blauen C, aber deutlich 
weniger Platine
- prozentual sehr viele analoge Bauteile, aber das Silizium war schon 
damals praktisch digital
==> 2021: wohl nicht mehr ganz aktuell

(+1): 32 CH PWM Board (230V via LED --> IR --> nacktes Silizium im 
Triac-Modus):
- PWM damals: pause width modulation (die Pause nach dem 
spannungslosen Moment im Niederspannungs-segment)
- Knight-Rider artige Lauflichter: programmiert in basic
- 40$ Miete von einem 'acid house': der Mieter hat sich die Lichteffekte 
vorher nicht angeschaut | ich hab die Soundeffekte vorher nicht gehört 
==> es wäre sinnvoll gewesen wenn sich zumindest einer von uns 
vorher informiert hätte
==> 2021: heutiges Einsteigerprojekt, vor 30 Jahren selten

(-1): analoges LED-Lauflicht (9V) ---
- reparaturfällig bereits nach ca. 3km auf dem Weg in die Antarktis
 (das Opfer des Lauflichts war zufällig später ein paar Monate auf dem 
Kontinent und hätte es theoretisch mitnehmen können)
==> 2021: wohl nicht mehr ganz aktuell

Mit der Selbstbeschränkung auf 1-bit (FI/LS-Krams) 8-bit µC und PC d.h. 
keine wagen Experimente mit analogem Silizium, FPGA, 32-bit µC etc. habe 
ich einfach Glück gehabt, dass sowas noch/wieder aktuell ist

NB.: ohne Arbeit, weil zufälliges lernen aus Neugier 0 Arbeit ist, 
während bezahltes vorsätzliches lernen selbst beim (nicht) erlernen von 
Tanzschritten echt Arbeit war

Die Arbeit, die in der Ablehnung/Gemekker von kreativen Ideen aus 
Büchern, 'Anfängern' (eigentlich selten wirkliche Anfänger, sondern 
häufig Hobbyisten) steckt, hilft nicht unbedingt etwas neues zu 
lernen.

> Jetzt könnt ihr Profis weiter mekkern...  stänkern und was weiss ich
> nicht und euer Wissen mit ins Grab nehmen...
das für dein Projekt technisch sinnvolle Wissen wird lieber zur 
Verbreitung von AVR-Daten über IP genutzt:
http://stefanfrings.de/net_io/protosockets.html
damit lassen sich multithreading Programme in C für kleine 
Mikrocontroller schreiben. Die Technologie wird nach Angabe der Webseite 
bereits von vielen Projekten benutzt.

Ein Port von ANSI-C auf gcc-C nutz ein besonderes Feature zur 
Kompatibilität mit asm,basic,fortran und C vor der Wende C89/C90: 
computed goto
https://github.com/LarryRuane/protothread
- "algorithm clarity" d.h. lesbarer Quelltext
- "efficiency" d.h. praktisch 0,x Overhead
- little-known gcc feature d.h. wenig bekannt bei ANSI-C aus der 
Industrie (Profi)
==> durch Larry Ruane werden Projekte wie "basic meets protothreads" 
realisierbar.

> Oder die nette freundlichkeit besitzen...
... wenn prothothreads nicht dazu genutzt werden können Gästezimmer 
schöner zu gestalten, sondern nur zur Verwaltung digitaler Pakete, 
dann dürfte derartigen Besitz selten sein.

> Das Forum so zu gebrauchen wie es soll...
"Mikrocontroller und Digitale Elektronik" sollte wohl mal neutral zur 
Diskussion über µC und digitale Elektronik gebraucht werden. Bei den 
sehr sehr vielseitigen Möglichkeiten digitaler Elektronik im Bereich 
Sound & Light ist eigentlich mit gelegentlichen Künstlern zu rechnen.
Für Profis gibt es ein extra Forum: "Ausbildung und Beruf"

Wenn man sich für Lichteffekte interessiert, dann kann man es wie 
Joachim machen:
Beitrag "Re: Wie macht man solche Lichtmodes? Lauflicht, PWM und Co"
- jeder Effekt ist einfach eine Funktion
- alternative:jeder Effekt ist einfach ein Task
LUA hat einen Scheduler eingbaut, bei C muss man halt bspw. protothreads 
bspw. aus den ethernet-modulen implementieren und wenn man ein paar 
Makros hat, dann kann zumindest im Stil wie basic/LUA schreiben
KISS: keep it simple stupid

NB.: ein Bekannter von mir hat im Hobby (irgendwas mit 
Maxwell-Gleichungen) so'nen Doktor in Analogkrams gemacht, sodass man 
sich halbwegs seriös über die historische Entwicklung bei den Spulen in 
den letzten 30 Jahren unterhalten kann (Menschen mit zu vielen Häusern 
fehlt häufig der Anreiz zum Geld verdienen)... 'jobbt' jetzt bei DSDS 
als Animateuer.....dürfte dort ziemlich albern sein .... . der würde 
genauso angemekkert, weil er formal wie Tischtennis-hilfe oder 
Mathe-hilfe (etwas) Geld bekommt und seine Kunden/Publikum wertschätz.

In Vorlesungen wird tw. mit meiste Zeit durch Anekdoten verbraucht.

> und mir netterweise etwas helfen?!
netterweise/kostenlos helfen Künstler und ähnliche Ideologen. Profis 
fragen zur Sicherheit vorher nach, ob sie helfen sollen, damit sie 
nicht umsonst arbeiten müssen (praktisch wie im Tante Emma).

von Stefan F. (Gast)


Lesenswert?

Ste, schreibe doch ein Buch, dann liest das vielleicht auch jemand.

Wenn das Buch allerdings fast nur mit pauschalisierten Anschuldigungen 
beginnt, ist der Nutzen gering und man wird wohl nach den ersten 20% 
nicht mehr weiter lesen, so wie es mir gerade bei deinem mühsam 
geschriebenen Aufsatz ging. Das ist schade um deine Zeit.

Zu einem Punkt möchte ich Stellung nehmen:

Ich beschreibe auf meiner Homepage wie man den Zustandsautomaten in C 
implementieren kann, weil die Zielgruppe des Artikel Leute sind, die in 
C Programmieren. Für diese Leute wäre es kontraproduktiv, hierzu eine 
andere Programmiersprache zu verwenden.

In der Reitschule lernt man bestimmte Manöver für Pferdekutschen 
schließlich auch nicht in einem PKW (obwohl beides gut ist und gelernt 
sein sollte).

von Stefan (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Bernd, schreibe doch ein Buch, dann liest das vielleicht auch jemand.
"_schön_  für den Einstieg"
Beitrag "Re: LabVIEW meets µC"
und die drohende fristlose Entlassung bei Hilfe für einem schönen 
Einstieg
Beitrag "Re: Analogwert im zweierkomplement seriel senden?"
(u.U. aufgrund von Faulheit)
zeigen, dass tw. wirklich so ein Risiko besteht.
Professor vom Berg versucht jetzt direkt zu helfen:
Beitrag "Re: Meßwert nach labview übertragen"

Stefan ⛄ F. schrieb:
> Für meine Leute wäre es kontraproduktiv, hierzu eine
> andere Programmiersprache zu verwenden
kontraproduktiv in 60 Tagen: 0 (C:NULL) Beispielcode mit 0 Einrückungen

Stefan ⛄ F. schrieb:
>> http://stefanfrings.de/net_io/protosockets.html
>> In diesem Aufsatz erkläre ich, wie man mit Hilfe von Protothreads
>> und Protosockets eigene Multithreading fähige Programme für kleine
>> Mikrocontroller schreibt. Viele Projekte benutzen diese Technologie,
> Zu einem Punkt möchte ich Stellung nehmen:
> Ich beschreibe auf meiner Homepage wie man den
> Zustandsautomaten in C implementieren kann.
Sorry,ich dachte nach den ersten 2% in dem Aufsatz würde erklärt, wie 
man mit Hilfe von Protothreads eigene Multithreading fähige Lauflicht 
& CO 
für AVR und andere kleine Mikrocontroller schreibt, die man mit einem 
kleinen Arduino-Projekt nutzten kann, um Stellung zum Thema zu nehmen:
https://wokwi.com/arduino/projects/307642111031771712
(für das Update habe ich ein paar Zeilen gekürzt und mit 
newTask/freeTask HEAP_tsk mMn. passendere Bezeichnungen gefunden)

Viele Projekte benutzen die Technologie lt. stefanfrings.de

von EAF (Gast)


Lesenswert?

Stefan schrieb:
> newTask

Alles klar: Keine Fragen mehr!
> macro "newTask" passed 3 arguments, but takes just 2


Ich glaube, dass ist das hässlichste Stück Arduino Code, was mit seit 
langem unter gekommen ist.
Wenn nicht sogar überhaupt.

von Falk B. (falk)


Lesenswert?

EAF schrieb:
> Ich glaube, dass ist das hässlichste Stück Arduino Code, was mit seit
> langem unter gekommen ist.
> Wenn nicht sogar überhaupt.

Naja, ich tippe mal wieder auf einen nicht mehr ganz so leicht 
autistischen Programmierer . . .

von Stefan F. (Gast)


Lesenswert?

>> Ich beschreibe auf meiner Homepage wie man den
>> Zustandsautomaten in C implementieren kann.

Stefan schrieb:
> Sorry,ich dachte nach den ersten 2% in dem Aufsatz würde erklärt,
> wie man mit Hilfe von Protothreads

Das ist ein anderer Artikel. Der Roman von "Ste" ist so lang und 
unübersichtlich, da kann das mal passieren.

von Stefan (Gast)


Lesenswert?

EAF (Gast)25.08.2021 11:19
>> Wie macht man solche Lichtmodes?
> Alles klar: Keine Fragen mehr!

Stefan ⛄ F. schrieb:
>> Wie macht man solche Lichtmodes?
>> http://stefanfrings.de/binaeruhr/index.html
> Das ist ein anderer Artikel.
... immerhin mit Flackereffekt wie vom Profi

Falk schrieb:
>> Wie macht man solche Lichtmodes?
> Naja, ich tippe mal wieder  . . .

von Stefan (Gast)


Lesenswert?

EAF schrieb:
>> macro "newTask" passed 3 arguments, but takes just 2
ups, ist doch tatsächlich ein falscher Link passiert:
https://wokwi.com/arduino/projects/308011153834902082

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.