Forum: Mikrocontroller und Digitale Elektronik Treppenstufenbeluchtung - Code Umbauen - Hilfe


von Scubydoo (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe in einem anderen Forum folgenden Code für eine 
Treppenstufenbeleuchtung gefunden. Dieser Code funktioniert soweit 
einwandfrei.

Auf der Platine sind Jumper zur Vorwahl der Anzahl an LEDs vorhanden. 
Die LEDs werden durch 2 Lichtschranken als INT0 und INT1 gesteuert.

Nun möchte ich dieses Script gerne verändern: Der Jumper soll durch 
einen Schalter ersetzt werden mit dem ich alle LEDs einschalten kann. So 
möchte ich quasi ein Dauerlicht erzeugen.

Es wäre nett, wenn mir einer bei der Umsetzung helfen könnte.

Ich muß ja quasi den Interrupt sperren und alle Ausgänge auf 1 setzen.

Habe schon ein bisschen probiert, aber irgendwie hat es nicht 
funktioniert.


Vielen Dank für eure Hilfe


Gruß

Scubydoo

Hier der Quelltext
1
/*
2
 * main.c
3
 *
4
 *  Created on: 14.10.2010
5
 *  (C) 2010 D.Goersch
6
 */
7
8
9
#include <avr/io.h>
10
#include <avr/pgmspace.h>
11
#include <avr/interrupt.h>
12
#include <util/delay.h>
13
#include <stdint.h>
14
#include "soft-pwm.h"
15
16
#define DELAY_FADE 11       // wait XX ms between each fade step
17
#define DELAY_LED 20      // wait XX ms between each LED
18
#define DURATION_SHORT 15    // autofade off after XX sec if jumper is open (high)
19
#define DURATION_LONG 25    // autofade off after XX sec if jumper is closed (low)
20
#define LTR 0          // Fade fom PortA0 forwards
21
#define RTL 1          // Fade from the last (amount) to PortA0 backwards
22
#define OFF 0          // State of
23
#define ON 1          // the LEDs
24
25
uint8_t amount=0;          // Amount of LEDs
26
uint8_t time;          // Fade-Off time
27
uint8_t direction;        // 0 - LTR 1 - RTL
28
uint8_t state=OFF;        // 0 - OFF 1 - ON
29
volatile uint8_t int0=0, int1=0;// flags for interrupts
30
volatile uint8_t tenms=0;     // +1 each 10ms
31
volatile uint8_t running=0;    // +1 each second
32
33
// dimming steps
34
uint8_t pwmtable[32] PROGMEM = {0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 11,
35
                                13, 16, 19, 23, 27, 32, 38, 45, 54, 64, 76,
36
                                91, 108, 128, 152, 181, 215, 255};
37
38
39
// patchtable for outputs
40
// uint8_t patchtable[24] PROGMEM = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
41
//                                  10, 11, 12, 13, 14, 15, 16,
42
//                                  17, 18, 19, 20, 21, 22, 23};
43
44
// patchtable for outputs (u.wehner)
45
uint8_t patchtable[24] PROGMEM = {0, 1, 2, 3, 4, 5, 6, 7, 23, 22,
46
          21, 20, 19, 18, 17, 16, 8, 9,
47
                                  10, 11, 12, 13, 14, 15};
48
49
50
void init(void);
51
void fade_on(uint8_t direction);
52
void fade_off(uint8_t direction);
53
54
int main(void)
55
{
56
  init();
57
58
  for(;;)
59
  {
60
61
    if(state==OFF)
62
    {
63
      if(int0 || int1) amount = ~((PIND & 0x03) | ((PIND >>2) & 0x1C)) & 0x1f;    // read PD0,1,4,5,6 as a dec. number
64
      if(int0)                  // if LEDs off, turn on LTR
65
      {
66
        state = ON;
67
        direction = LTR;
68
        fade_on(direction);
69
        int0 = 0;
70
71
        TCNT0 = 100;              // Preload
72
        TCCR0 |= (1<<CS00) | (1<<CS02);      // Timer0 prescaler 1024
73
      }
74
      else if(int1)                // LEDs off, turn on RTL
75
      {
76
        state = ON;
77
        direction = RTL;
78
        fade_on(direction);
79
        int1 = 0;
80
81
        TCNT0 = 100;              // Preload
82
        TCCR0 |= (1<<CS00) | (1<<CS02);      // Timer0 prescaler 1024
83
      }
84
    }
85
    else if(state==ON)
86
    {
87
      if((!time & (running >= DURATION_SHORT)) | (time & (running >= DURATION_LONG))) {  // turn of automaticly
88
        TCCR0 = 0;                // disable timer0
89
        tenms = 0; running = 0;          // reset turnoff-timer
90
        fade_off(direction);
91
        state = OFF;
92
93
      }
94
      if(int0 & (direction==LTR)) int0=0;      // LEDs LTR on, left switch ignored
95
      else if(int1 & (direction==RTL)) int1=0;  // LEDS RTL on, right switch ignored
96
      else if(int0 & (direction==RTL))      // LEDs RTL on, fade off on left switch
97
      {
98
        TCCR0 = 0;                // disable timer0
99
        tenms = 0; running = 0;          // reset turnoff-timer
100
        fade_off(direction);
101
        state = OFF;
102
        int0 = 0;
103
      }
104
      else if(int1 & (direction==LTR))      // LEDs LTR on, fade off on right switch
105
      {
106
        TCCR0 = 0;                // disable timer0
107
        tenms = 0; running = 0;          // reset turnoff-timer
108
        fade_off(direction);
109
        state = OFF;
110
        int1 = 0;
111
      }
112
    }
113
  }
114
}
115
116
// do basic initialisation
117
void init(void)
118
{
119
  DDRA = 0xff;  // PortA
120
  DDRB = 0xff;  // PortB
121
  DDRC = 0xff;  // PortC as Output
122
  DDRD = 0x00;  // PortD as Input
123
  PORTD = 0xff;  // PullUps on PortD
124
125
//  moved to mainloop
126
//  amount = ~((PIND & 0x03) | ((PIND >>2) & 0x1C)) & 0x1f;    // read PD0,1,4,5,6 as a dec. number
127
  time   = PIND & 0x20;                    // read PinD5 as fadeout mode
128
129
//  activated in mainloop after LEDs on
130
//  TCCR0 |= (1<<CS00) | (1<<CS02);  // Timer0 prescaler 1024
131
  TCNT0 = 100;          // Preload
132
  TIMSK |= (1<<OCIE0);      // enable Timer0
133
134
  TCCR1B = 1;               // Timer1 runs full system clock
135
    TIMSK |= (1<<OCIE1A);     // enable Timer1
136
137
    MCUCR |= (1<<ISC01);    // INT0 on falling edge
138
    MCUCR |= (1<<ISC11);    // INT1 on falling edge
139
    GICR |= (1<<INT0);      // enable INT0
140
    GICR |= (1<<INT1);      // enable INT1
141
142
    sei();
143
}
144
145
// fade the LEDs on
146
void fade_on(uint8_t direction)
147
{
148
  if (direction == LTR)
149
  {
150
    for(uint8_t led=0;led<amount;led++)
151
    {
152
      for(uint8_t bri=0;bri<32;bri++)
153
      {
154
        pwm_setting[pgm_read_byte(patchtable+led)] = pgm_read_byte(pwmtable+bri);
155
//        pwm_setting[patchtable[led]] = pwmtable[bri];
156
        _delay_ms(DELAY_FADE);
157
      }
158
      _delay_ms(DELAY_LED);
159
    }
160
  }
161
  else
162
  {
163
    for(uint8_t led=amount;led>0;led--)
164
    {
165
      for(uint8_t bri=0;bri<32;bri++)
166
      {
167
        pwm_setting[pgm_read_byte(patchtable+(led-1))] = pgm_read_byte(pwmtable+bri);
168
        _delay_ms(DELAY_FADE);
169
      }
170
      _delay_ms(DELAY_LED);
171
    }
172
  }
173
}
174
175
// fade the LEDs off
176
void fade_off(uint8_t direction)
177
{
178
  if (direction == LTR)
179
  {
180
    for(uint8_t led=0;led<amount;led++)
181
    {
182
      for(uint8_t bri=32;bri>0;bri--)
183
      {
184
        pwm_setting[pgm_read_byte(patchtable+led)] = pgm_read_byte(pwmtable+bri-1);
185
        _delay_ms(DELAY_FADE);
186
      }
187
      _delay_ms(DELAY_LED);
188
    }
189
  }
190
  else
191
  {
192
    for(uint8_t led=amount;led>0;led--)
193
    {
194
      for(uint8_t bri=32;bri>0;bri--)
195
      {
196
        pwm_setting[pgm_read_byte(patchtable+(led-1))] = pgm_read_byte(pwmtable+bri-1);
197
        _delay_ms(DELAY_FADE);
198
      }
199
      _delay_ms(DELAY_LED);
200
    }
201
  }
202
}
203
204
// set flags on interrupts
205
ISR(INT0_vect) { int0 = 1; }
206
ISR(INT1_vect) { int1 = 1; }
207
208
// timer for auto-off
209
ISR(TIMER0_COMP_vect)
210
{
211
  tenms++;
212
  if (tenms >= 100)
213
  {
214
    running++;
215
    tenms = 0;
216
  }
217
}

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

Scubydoo schrieb:
> Habe schon ein bisschen probiert, aber irgendwie hat es nicht
> funktioniert.

was (wo) ist "ein bichen", und was ist "irgendwie"?

Solche Aussagen zwecks Fehleranalyse und Unterstützungshilfe sind so 
sinnvoll wie mein Tip: "Du must irgendwie irgendwas an dem Programmcode 
ändern, um die gewünschte Funktion zu erhalten."

von Jonas B. (jibi)


Lesenswert?

Ist das der verfuschte Code oder das Original?

Gruß Jonas

von Sven W. (Firma: basement industries) (dj8nw)


Lesenswert?

#include "soft-pwm.h"

^...geht das?

von Krapao (Gast)


Lesenswert?

Wenn du die Jumper für die Anzahl der LEDs anders benutzt und die 
Lichtschranken nicht mehr benutzt, was bleibt dann vom Originalprogramm?
Wäre es da nicht sinnvoller ein eigenes Programm zu schreiben?
Braucht man dafür überhaupt einen µC oder reicht eine AN/AUS Schaltung?

Beim vorhandnen Programm solltest du Dauerlicht bekommen, wenn

* die Lichtschranke fürs Einschalten mit dem Schalter so eingestellt 
wird, dass immer der betreffende Interrupt ausgelöst wird (ODER, 
Schalter parallel)

* und die Lichtschranke für das Ausschalten so eingestellt wird, dass 
nie ein Interrupt ausgelöst wird (UND, Schalter in Serie)

* das time auto-off im Code auskommentiert wird (z.B. running nicht 
hochzählen).

Schaltplan und Beschreibng der Originalschaltung wäre nicht schlecht.

von Daniel B. (scubydoo)


Angehängte Dateien:

Lesenswert?

Hallo,

danke für die erste Hilfestellung:

1) Ja, das Programm ist original und nicht "verpfuscht"

2) Schaltplan und die Include Dateien habe ich mal angehängt

3) Ich habe mir das so vorgestellt, dass bei geöffnetem Schalter die 
LEDs nacheinander an-/bzw. ausgehen. So wie es zur Zeit läuft. Lege ich 
den Schalter um, bleiben alle LEDs an. Und das unabhängig ob jemand 
durch die Lichtschranken läuft (INT0/INT1) oder nicht.

Auskommentieren ist also nicht!

4.) Versucht habe ich folgendes:
In Zeile 63: if(int0 || int1) amount = ~((PIND & 0x03) | ((PIND >>2) & 
0x1C)) & 0x1f;    // read PD0,1,4,5,6 as a dec. number

steht meiner Meinung nach die Abfrage der Jumper. Das habe ich über die 
For Schleife kopiert und nur nach z.B. PIND7 abgefragt. Dann wollte ich 
mit  PORTA = 0xFF; alle Ausgänge setzen.

Aber so ganz hat das nicht funktioniert.

Nun die Frage: Was muß ich wo einfügen um meine Idee umsetzen zu können.


Danke und Gruß

Scubydoo

von Krapao (Gast)


Lesenswert?

> 2) Schaltplan und die Include Dateien habe ich mal angehängt

Welche Lichtschranken hängen wie an IN 1 und IN 2?
Wie hast du den/die Schalter derzeit angeschlossen?

> Auskommentieren ist also nicht!

Dann mach diesen time auto-off Teil und und die Reaktion aut int0/int1 
von einem Pinzustand abhängig. Hast du noch einen freien Pin am AVR, 
z.B. einen auf JP1, den du mit dem Schalter füttern kannst?

von guest (Gast)


Lesenswert?

Tippfehler suchen macht besoffen doppelt so viel Spaß!

von Daniel B. (scubydoo)


Lesenswert?

Die Lichtschranken hängen per Masse an IN1. Sind NPN-Lichtschranken

Schalter habe ich im Moment keinen dran. Der Versuch ist ja gescheitert!

Jumper ist noch frei. Die Anzahl der LEDs braucht nicht variabel zu 
sein. Daher kann ich PD7 für einen Taster nehmen

Wo muß das im Code implementiert werden?

von Krapao (Gast)


Lesenswert?

> Daher kann ich PD7 für einen Taster nehmen

Wie jetzt, Taster oder Jumper/Schalter?

Hier die Fassung mit Jumper/Schalter, d.h. der Schaltzustand braucht die 
Software nicht zu archivieren, sondern kann stets das Bauteil abfragen.

1
uint8_t dauerlicht(void)
2
{
3
  DDRD &= ~(1<<PD7); // PD7 Eingang
4
  PORTD |= (1<<PD7); // interner Pullup an
5
  asm volatile("nop");
6
  return (PIND & (1<<PD7)) ^ (1<<PD7); // active-low Jumper/Schalter
7
}
8
9
int main(void)
10
{
11
  init();
12
13
  // Abfrage der Anzahl LEDs hochgezogen 
14
  // (Ändert sich im Betrieb ja wohl nicht, oder)?
15
  // read PD0,1,4,5,6 as a dec. number
16
  amount = ~((PIND & 0x03)|((PIND >>2) & 0x1C)) & 0x1f;    
17
18
  for(;;)
19
  {
20
    if (dauerlicht() && state==OFF)
21
    {
22
      state = ON;
23
      direction = LTR; // je nach Gusto
24
      fade_on(direction);
25
      TCNT0 = 100;
26
      TCCR0 |= (1<<CS00) | (1<<CS02); // Timer0 prescaler 1024
27
    }
28
    else if (dauerlicht() && state==ON)
29
    {
30
      // Auto-off auf z.B. 3 Sekunden setzen für den Fall,
31
      // dass Dauerlicht ausgeschaltet wird
32
      running = time ? DURATION_LONG-3 : DURATION_SHORT-3;
33
    }
34
    else if(state==OFF)// && !dauerlicht()
35
    {
36
      ... wie vorher aber Fehler &, | zu &&, || korrigieren!
37
    }
38
    else if(state==ON) // && !dauerlicht()
39
    {
40
      ... wie vorher aber Fehler &, | zu &&, || korrigieren!
41
    }
42
  }
43
}

von Daniel B. (scubydoo)


Lesenswert?

Hallo Krapao,

vielen vielen Dank für Deine Hilfe.
Es wird ein Schalter. Sorry für die Verwirrung!


Diesen Absatz verstehe ich leider nicht

else if(state==OFF)// && !dauerlicht()
    {
      ... wie vorher aber Fehler &, | zu &&, || korrigieren!
    }
    else if(state==ON) // && !dauerlicht()
    {
      ... wie vorher aber Fehler &, | zu &&, || korrigieren!
    }

Kannst Du mir das vielleicht etwas näher erklären?

DANKE!


Im Originalcode sind ja noch weitere if bzw elseif Abfragen:

if(int0 & (direction==LTR)) int0=0;      // LEDs LTR on, left switch 
ignored
      else if(int1 & (direction==RTL)) int1=0;  // LEDS RTL on, right 
switch ignored
      else if(int0 & (direction==RTL))      // LEDs RTL on, fade off on 
left switch
      {
        TCCR0 = 0;                // disable timer0
        tenms = 0; running = 0;          // reset turnoff-timer
        fade_off(direction);
        state = OFF;
        int0 = 0;
      }
      else if(int1 & (direction==LTR))      // LEDs LTR on, fade off on 
right switch
      {
        TCCR0 = 0;                // disable timer0
        tenms = 0; running = 0;          // reset turnoff-timer
        fade_off(direction);
        state = OFF;
        int1 = 0;
      }


Diese benötige ich aber weiterhin, oder?
Aber eine Schalterabfrage muß da nicht mehr hin.


Danke und Gruß

Scubydoo

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.