Treppenstufenbeluchtung - Code Umbauen - Hilfe

Gast #2557725
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
}
Angehängte Dateien:
Gast #2557765
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.
#2557892
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
Angehängte Dateien:
Gast #2557926
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?
#2558099
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?
Gast #2558259
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
}
#2559200
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren