Hallo,
ich habe eine Helligkeitssteuerrung auf meinen Mega2560 entwickelt. Diese habe ich jetzt auf einen Genuino Micro übertragen. Das einzigste was sich änderte war der Hardwarepin vom Timer 1. Von Pin 12 auf 10.
In 2 Dingen verhält sich der Micro anders. Nehme ich per USB den Saft weg und wieder ran, startet er wie er soll. Programm legt sofort los. Mache ich einen Reset per Taster, blinkt erst eine Weile seine LED13, dann erst gehts los.
Komisch?
Aber meine eigentliche LED an Pin 10 reagiert erst normal auf meinen Sketch, wenn ich den seriellen Monitor öffne. Ansonsten ist ihr PWM Wert immer konstant. Das sehe ich am Logic Analyzer.
Mit dem Mega gab es nie Probleme bis jetzt.
Was ist hier los?
/*
Doc_Arduino - german Arduino Forum
IDE 1.6.6
Arduino Micro
LED Helligkeitssteuerung
Timer 1: Phase & Frequenz Correct, Mode 9
TOP: OCR1A (Takt-Frequenz)
Pulsweite: OCR1 (<= TOP)
Schaltpin: 10 (OC1B bzw. PB6) nicht invertiert
*/
#include <avr/pgmspace.h>
const byte _LEDpin = 10; // OC1B bzw. PB6 nicht invertiert
const byte _Pot1pin = A0; // Potentiometer, Minimum Helligkeit
const byte _Pot2pin = A1; // Potentiometer, Maximal Helligkeit
const byte _LDR1pin = A2; // LDR
const byte _LDR2pin = A3; // LDR
float _LDR_filt; // gefilteter gleitender LDR Mittelwert
int _Index_PWM_Table;
const int PWM_Table[99] PROGMEM = // 10 Bit, 99 aus 128 Werten, Gammakorrektur 3,0
{0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,3,3,4,5,5,6,7,8,9,10,11,12,13,
15,16,18,20,21,23,25,27,30,32,34,37,40,43,46,49,52,55,59,62,66,70,
74,79,83,88,92,97,103,108,113,119,125,131,137,144,150,157,164,171,
179,186,194,202,211,219,228,237,246,256,265,275,286,296,307,318,
329,340,352,364,376,389,402,415,428,442,456,470}; // letzte Indexposition 98
void setup() {
Serial.begin(9600);
digitalWrite(_LEDpin, LOW); // OC1B bzw. PB6 nicht invertiert
pinMode(_LEDpin, OUTPUT);
set_Timer1();
DemoFading();
}
void loop() {
_Index_PWM_Table = calculate_PWM();
refresh_LED(_Index_PWM_Table);
} // Ende loop()
// ****** Funktionen ******* //
int calculate_PWM ()
{
int LDR1 = analogRead(_LDR1pin);
Serial.print("LDR1 ");Serial.print(LDR1);Serial.print(" ");
int LDR2 = analogRead(_LDR2pin);
Serial.print("LDR2 ");Serial.print(LDR2);Serial.print(" ");
int minBrightness = analogRead(_Pot1pin)/53+21; // minimum Index Bereich 21 ... 40 möglich
int maxBrightness = analogRead(_Pot2pin);
maxBrightness = map(maxBrightness, 0, 1023, 50, 98); // muß <= höchstem PWM_Table Index bleiben
Serial.print("min ");Serial.print(minBrightness);Serial.print(" ");
Serial.print("max ");Serial.print(maxBrightness);Serial.print(" ");
int LDR = (LDR1+LDR2)/2;
Filtern(_LDR_filt, LDR, 500);
int Index_PWM_Table = map(_LDR_filt, 0, 1023, minBrightness, maxBrightness);
Serial.print("Index ");Serial.print(Index_PWM_Table);Serial.print(" ");
return Index_PWM_Table;
}
void refresh_LED (int Index_PWM_Table)
{
int PWM_Wert = pgm_read_word_near(PWM_Table + Index_PWM_Table);
OCR1B = PWM_Wert;
Serial.print("PWM Wert ");Serial.println(PWM_Wert);
}
void DemoFading() // einmalig beim Start
{
static unsigned long lastTime;
static unsigned int stepTime = 15;
static unsigned int Index_PWM_Table = 0;
for (int i=0; i<=98;) { // Fading IN
if (millis() - lastTime > stepTime ) { // Fading Geschwindigkeit einhalten
Index_PWM_Table = i; // PWM_Table Index Position anpassen
lastTime = millis();
i++;
}
refresh_LED(Index_PWM_Table);
_Index_PWM_Table = calculate_PWM();
}
stepTime = stepTime+15;
for (int i=97; i>=29;) { // Fading OUT
if (millis() - lastTime > stepTime ) { // Fading Geschwindigkeit einhalten
Index_PWM_Table = i; // PWM_Table Index Position anpassen
lastTime = millis();
i--;
}
refresh_LED(Index_PWM_Table);
_Index_PWM_Table = calculate_PWM();
}
stepTime = stepTime+10;
for (int i=29; i<=_Index_PWM_Table;) { // Fading IN
if (millis() - lastTime > stepTime ) { // Fading Geschwindigkeit einhalten
Index_PWM_Table = i; // PWM_Table Index Position anpassen
lastTime = millis();
i++;
}
refresh_LED(Index_PWM_Table);
_Index_PWM_Table = calculate_PWM();
}
delay(1000);
}
void set_Timer1() // 10 Bit PWM, Phase Frequency Correct, Mode 9
{
cli(); // Interrupts ausschalten
TCCR1A = 0; // Reset TCCR1A Register
TCCR1B = 0; // Reset TCCR1B Register
TIMSK1 = 0; // Reset TIMSK1 Register (disable Timer Compare Interrupts)
TCNT1 = 0; // initialize counter value to 0
TCCR1A = (1<<COM1B1) | (1<<WGM10); // nicht invertiert
TCCR1B = (1<<WGM13) | (1<<CS11); // Prescaler 8 >> 977,5Hz (TOP 1023)
OCR1A = 1023; // TOP Wert bestimmt mit Prescaler den PWM Takt
OCR1B = 0; // Pulsweite, OCR1x <= 1023 (2^10)
sei(); // Interrupts einschalten
} // end Funktion
/****************************************************************************************
** Funktion Filtern() by GuntherB **
*****************************************************************************************
** Bildet einen Tiefpassfilter (RC-Glied) nach. **
** FF = Filterfaktor; Tau = FF / Aufruffrequenz ** **
** Input: FiltVal der gefilterte Wert, NewVal der neue gelesene Wert; FF Filterfaktor **
** Output: FiltVal **
** genutzte Globale Variablen: _LDR_filt (call by Reference) **
*****************************************************************************************/
void Filtern(float &FiltVal, int NewVal, int FF){
FiltVal= ((FiltVal * FF) + NewVal) / (FF +1);
}