Skocz do zawartości

Adaptacja kodu do Teensy3.5


Prot1976

Pomocna odpowiedź

Witajcie,

W czeluściach intereneta natknąłem się na kod pisany na Arduino z zegarem RTC1307, opis działania i oryginalny kod znajduje się pod linkiem poniżej.

https://github.com/benjaf/LightController/tree/master/Arduino/LightController

Udało mi się podmienić bibliotekę RTC i częściowo zmienić kod i o ile udało mi się wysłać odczyt zegara na Serial Monitor to już bieżące wartości dla przykładowych kanałów są dla mnie nieosiągalne.

 

/*
 * Name:  LightController.ino
 * Author:  User "benjaf" at plantedtank.net forums
 * URL:   https://github.com/benjaf/LightController
 * This example is set up for 2 channels with a maximum of 10 points.
 * Anything that may require editing is labeled with ¤CHANGE¤
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. 
 */

// ----------------------- RTC Library -----------------------


#include "ChannelManager.h"
#include <TimeLib.h>

// ----------------------- Constants -----------------------
// ¤CHANGE¤
const int MaxChannels = 2;   // Max number of channels, change if more or less are required
const int MaxPoints = 10;    // Max number of light intensity points, change if more or less are required

// ----------------------- Variables -----------------------
// RTC
//RTC_DS1307 RTC;

// Time
//DateTime CurrentTime;
time_t CurrentTime;
// ----------------------- Lights -----------------------

// Schedule Point format: (Hour, Minute, Intensity)
// Difference in intensity between points is faded/increased gradually
// Example: 
// Channels[0].AddPoint(8, 0, 0);
// Channels[0].AddPoint(8, 30, 255);
// Channels[0].AddPoint(11, 0, 255);
//  ...
//
// Explanation:
//  00:00 - 08:00 -> Light OFF
//  08:00 - 08:30 -> Increment light towards Fully ON
//  08:30 - 11:00 -> Light Fully ON
//
// Min intensity value: 0 (OFF)
// Max intensity value: 255 (Fully ON)
//
// If only 1 point is added, channel always maintains value of that point
//
// There is the option of which fade mode to use.
// Basically there are 2 modes: Linear and Exponential
// - Linear is what you would expect - 50% on = 50% duty cycle.
// - Exponential is an estimation of how our eyes react to brightness. The 'real' formula is actually inverse logarithmic,
//   but for our use exponential is close enough (feel free to add more fade modes if you disagree) - and much faster to compute!

Channel Channels[MaxChannels];
Point Points[MaxChannels][MaxPoints];

// Add more timing definitions here if more channels are added:
// ¤CHANGE¤
void InitializeChannels(int channels) {
  // Channel 0: (Example)
  // This is an example of a typical lighting schedule (Lights on 08:30 - 19:00 w. 30 minutes of sunrise / sunset added)
  // using linear fading on pin 10.
  
  //int channelNo = 0;
  //int pin = 10;
  //Channels[channelNo] = Channel(pin, MaxPoints, fademode_linear, Points[channelNo]);
  //Channels[channelNo].AddPoint(8, 0, 0);
  //Channels[channelNo].AddPoint(8, 30, 255);
  //Channels[channelNo].AddPoint(19, 0, 255);
  //Channels[channelNo].AddPoint(19, 30, 0);
    
  // Channel 0:
  int channelNo = 0;  // Currently editing channel 0
  int pin = 13;   // Channel 0 uses pin 10
  Channels[channelNo] = Channel(pin, MaxPoints, fademode_linear, Points[channelNo]);  // Initialize channel and choose FadeMode
  Channels[channelNo].AddPoint(8, 0, 0);  // Add Point (can also use decimal values ranging from 0 to 1 if you prefer)
  Channels[channelNo].AddPoint(8, 0, 0);
  Channels[channelNo].AddPoint(8, 30, 150);
  Channels[channelNo].AddPoint(10, 16, 0);
  Channels[channelNo].AddPoint(10, 21, 255);
  Channels[channelNo].AddPoint(10, 26, 0);
  Channels[channelNo].AddPoint(12, 45, 255);
  Channels[channelNo].AddPoint(19, 30, 150);
  Channels[channelNo].AddPoint(20, 0, 0);
  
  // Channel 1:
  channelNo = 1;  // Currently editing channel 1
  pin = 11;   // Channel 1 uses pin 11
  Channels[channelNo] = Channel(pin, MaxPoints, fademode_linear, Points[channelNo]);
  Channels[channelNo].AddPoint(8, 0, 0);
  Channels[channelNo].AddPoint(15, 55, 0);
  Channels[channelNo].AddPoint(15, 56, 0);
  Channels[channelNo].AddPoint(15, 57, 255);
  Channels[channelNo].AddPoint(15, 58, 0);
  Channels[channelNo].AddPoint(20, 0, 0);
}

// ----------------------- Functions -----------------------
long lastUpdateTime = 0;

// Update light intensity values
void UpdateLights(time_t currentTime)
//void UpdateLights()
{
  long now = Seconds(hour(), minute(), second()); // Convert current time to seconds since midnight
  if(now != lastUpdateTime)   // Perform update only if there is a perceivable change in time (no point wasting clock cycles otherwise)
  {
    for(int channel = 0; channel < MaxChannels; channel++)        // For each Channel
    {
      analogWrite(Channels[channel].GetPin(), Channels[channel].GetLightIntensityInt(now));
     }
  }
  lastUpdateTime = now;
}


// Convert HH:mm:ss -> Seconds since midnight
long Seconds(int hour, int minute, int second) {
  return ((long)hour * 60 * 60) + (minute * 60) + second ;
}

// ----------------------- Setup -----------------------
void setup() {
  // Initialize channel schedules
  InitializeChannels(MaxChannels);
  // set the Time library to use Teensy 3.0's RTC to keep time
  setSyncProvider(getTeensy3Time);

  Serial.begin(115200);
  while (!Serial);  // Wait for Arduino Serial Monitor to open
  delay(100);
  if (timeStatus()!= timeSet) {
    Serial.println("Unable to sync with the RTC");
  } else {
    Serial.println("RTC has set the system time");
  }
  
  
  // Clock
//  Wire.begin();
//  RTC.begin();
  //RTC.adjust(DateTime(__DATE__, __TIME__));  // Set RTC time to sketch compilation time, only use for 1 (ONE) run. Will reset time at each device reset!
}

// ----------------------- Loop -----------------------
void loop() {
  // Get current time
  //CurrentTime = RTC.now();
  CurrentTime = Teensy3Clock.get();
  
  // Update lights
  UpdateLights(CurrentTime);
  if (Serial.available()) {
    time_t t = processSyncMessage();
    if (t != 0) {
      Teensy3Clock.set(t); // set the RTC
      setTime(t);
    }
  }
  digitalClockDisplay();
  int ch1_value = analogRead(13);
  Serial.println(ch1_value);
//  Serial.println(Seconds);
 }

void digitalClockDisplay() {
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.print(" ");
  Serial.println(Teensy3Clock.get());
  Serial.println(now());
//  Serial.print(Seconds());
  Serial.print(" ");
  Serial.println();  
  }

time_t getTeensy3Time()
{
  return Teensy3Clock.get();
}

/*  code to process time sync messages from the serial port   */
#define TIME_HEADER  "T"   // Header tag for serial time sync message

unsigned long processSyncMessage() {
  unsigned long pctime = 0L;
  const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 

  if(Serial.find(TIME_HEADER)) {
     pctime = Serial.parseInt();
     return pctime;
     if( pctime < DEFAULT_TIME) { // check the value is a valid time (greater than Jan 1 2013)
       pctime = 0L; // return 0 to indicate that the time is not valid
     }
  }
  return pctime;
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

Prosiłbym o wskazówki o co chodzi w kilku miejscach oryginalnego kodu:

o co chodzi w tym fragmencie

// ----------------------- Variables -----------------------
// RTC
RTC_DS1307 RTC;

// Time
DateTime CurrentTime;

I w tym fragmencie:

// ----------------------- Functions -----------------------
long lastUpdateTime = 0;

// Update light intensity values
void UpdateLights(DateTime currentTime)
{
	long now = Seconds(currentTime.hour(), currentTime.minute(), currentTime.second());	// Convert current time to seconds since midnight
	if(now != lastUpdateTime)  	// Perform update only if there is a perceivable change in time (no point wasting clock cycles otherwise)
	{
		for(int channel = 0; channel < MaxChannels; channel++)    		// For each Channel
		{
			analogWrite(Channels[channel].GetPin(), Channels[channel].GetLightIntensityInt(now));	// Get updated light intensity and write value to pin (update is performed when reading value)
		}
	}
	lastUpdateTime = now;
}


// Convert HH:mm:ss -> Seconds since midnight
long Seconds(int hours, int minutes, int seconds) {
	return ((long)hours * 60 * 60) + (minutes * 60) + seconds ;
}

i jak w serial monitor wyświetlić wartości zapisywane dla każdego kanału (w testowym kodzie są 2 ale docelowo może być więcej):

analogWrite(Channels[channel].GetPin(), Channels[channel].GetLightIntensityInt(now)); // Get updated light intensity and write value to pin (update is performed when reading value)

Będę wdzięczny za wskazówki

Pozdrawiam

K

Link do komentarza
Share on other sites

Dnia 20.03.2019 o 21:01, Prot1976 napisał:

Witajcie,

W czeluściach intereneta natknąłem się na kod pisany na Arduino z zegarem RTC1307, opis działania i oryginalny kod znajduje się pod linkiem poniżej.

https://github.com/benjaf/LightController/tree/master/Arduino/LightController

Udało mi się podmienić bibliotekę RTC i częściowo zmienić kod i o ile udało mi się wysłać odczyt zegara na Serial Monitor to już bieżące wartości dla przykładowych kanałów są dla mnie nieosiągalne.

 

Prosiłbym o wskazówki o co chodzi w kilku miejscach oryginalnego kodu:

o co chodzi w tym fragmencie


// ----------------------- Variables -----------------------
// RTC
RTC_DS1307 RTC;

// Time
DateTime CurrentTime;

 

Pozdrawiam

W tym fragmencie masz deklaracje dwóch zmiennych:

1) zmiennej o nazwie RTC która jest typu RTC_DS1307

2) zmiennej CurrentTime która jest typu DateTime.

Zacznijmy może od typu RTC_DS1307  i zmiennej RTC która jest po prostu instancją zegara czasu rzeczywistego opartego o układ DS1307. Jak zajrzymy do źródeł, które wymieniłeś:

https://github.com/benjaf/LightController/blob/master/Arduino/LightController/LightController.ino

// ----------------------- RTC Library -----------------------
// Use Wire and RTClib (https://github.com/adafruit/RTClib):
// Please note that there are a significant differences between the original JeeLabs RTCLib and the Adafruit fork!
#include <Wire.h>
#include "RTClib.h"
#include "ChannelManager.h"

Jak widać na poczatku programu LightController na początku programu dołącza kod trzech plików nagłówkowych. Obydwie zadeklarowane zmienne są w bibliotece RTCLib (pilk: "RTCLib.h"). Tutaj link do tej biblioteki:

https://github.com/adafruit/RTClib

Nas interesuje plik RTClib.cppk bo tam są definicje typów RTC_DS1307 i Datetime:

https://github.com/adafruit/RTClib/blob/master/RTClib.cpp

Implementacja typu RTC_DS1307 zaczyna się od linii 233 powyższego pliku (i tam można zobaczyć jakie metody ma zadeklarowane):

////////////////////////////////////////////////////////////////////////////////
// RTC_DS1307 implementation

static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); }
static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); }

boolean RTC_DS1307::begin(void) {
  Wire.begin();
  return true;
}

Natomiast typ DateTime przechowuje jednocześnie datę i dokładny czas jakiegoś zdarzenia. Jego implementacja zaczyna się od linii 70

////////////////////////////////////////////////////////////////////////////////
// DateTime implementation - ignores time zones and DST changes
// NOTE: also ignores leap seconds, see http://en.wikipedia.org/wiki/Leap_second

DateTime::DateTime (uint32_t t) {
  t -= SECONDS_FROM_1970_TO_2000;    // bring to 2000 timestamp from 1970

    ss = t % 60;
    t /= 60;
    mm = t % 60;
    t /= 60;
    hh = t % 24;
    uint16_t days = t / 24;
uint8_t leap;

Klasa ma kilka przeciążonych konstruktorów, dla Ciebie może najbardziej interesujący może być ten zaczynający się od linii 101 wyżej wymienionego pliku:

DateTime::DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) {
    if (year >= 2000)
        year -= 2000;
    yOff = year;
    m = month;
    d = day;
    hh = hour;
    mm = min;
    ss = sec;
}

Dzięki temu konstruktorowi możesz się dokładanie zorientować jakie  składowe budują ten typ.

Dnia 20.03.2019 o 21:01, Prot1976 napisał:

Witajcie,

W czeluściach intereneta natknąłem się na kod pisany na Arduino z zegarem RTC1307, opis działania i oryginalny kod znajduje się pod linkiem poniżej.

https://github.com/benjaf/LightController/tree/master/Arduino/LightController

Prosiłbym o wskazówki o co chodzi w kilku miejscach oryginalnego kodu:

o co chodzi w tym fragmencie

I w tym fragmencie:


// ----------------------- Functions -----------------------
long lastUpdateTime = 0;

// Update light intensity values
void UpdateLights(DateTime currentTime)
{
	long now = Seconds(currentTime.hour(), currentTime.minute(), currentTime.second());	// Convert current time to seconds since midnight
	if(now != lastUpdateTime)  	// Perform update only if there is a perceivable change in time (no point wasting clock cycles otherwise)
	{
		for(int channel = 0; channel < MaxChannels; channel++)    		// For each Channel
		{
			analogWrite(Channels[channel].GetPin(), Channels[channel].GetLightIntensityInt(now));	// Get updated light intensity and write value to pin (update is performed when reading value)
		}
	}
	lastUpdateTime = now;
}


// Convert HH:mm:ss -> Seconds since midnight
long Seconds(int hours, int minutes, int seconds) {
	return ((long)hours * 60 * 60) + (minutes * 60) + seconds ;
}

 

 

W tym fragmencie mamy trzy definicje:

1) Zmiennej  lastUpdateTime (typu long), której przypisujemy wartość 0:

long lastUpdateTime = 0;

2) funkcji UpdateLights, która przyjmuje jeden argument typu DateTime (aktualny czas):

// Update light intensity values
void UpdateLights(DateTime currentTime)
{
	long now = Seconds(currentTime.hour(), currentTime.minute(), currentTime.second());	// Convert current time to seconds since midnight
	if(now != lastUpdateTime)  	// Perform update only if there is a perceivable change in time (no point wasting clock cycles otherwise)
	{
		for(int channel = 0; channel < MaxChannels; channel++)    		// For each Channel
		{
			analogWrite(Channels[channel].GetPin(), Channels[channel].GetLightIntensityInt(now));	// Get updated light intensity and write value to pin (update is performed when reading value)
		}
	}
	lastUpdateTime = now;
}

3) funkcji Seconds, która jako argumenty przyjmuje aktualną godzinę, minuty i sekundy:

// Convert HH:mm:ss -> Seconds since midnight
long Seconds(int hours, int minutes, int seconds) {
	return ((long)hours * 60 * 60) + (minutes * 60) + seconds ;
}

Funkcja ta zwraca ilość sekund jakie upłynęły od północy do podanej godziny.

------------------------------------------------

Funkcja UpdateLights jako argument przyjmuje aktualny moment w czasie (data i dokładna godzina). Najpierw jest wyznaczony moment w czasie now - ile sekund upłynęło od północy, Jeśli now nie jest równe ostatniemu update - zmienna lastUpdateTime, to modyfikowane są jasności kanałów świateł za pomocą fukcji analogWrite (PWM), Jako ostatni krok zmienna lastUpdateTime jest modyfikowana na now.

Dnia 20.03.2019 o 21:01, Prot1976 napisał:

Witajcie,

W czeluściach intereneta natknąłem się na kod pisany na Arduino z zegarem RTC1307, opis działania i oryginalny kod znajduje się pod linkiem poniżej.

https://github.com/benjaf/LightController/tree/master/Arduino/LightController

Prosiłbym o wskazówki o co chodzi w kilku miejscach oryginalnego kodu:

o co chodzi w tym fragmencie

I w tym fragmencie:

i jak w serial monitor wyświetlić wartości zapisywane dla każdego kanału (w testowym kodzie są 2 ale docelowo może być więcej):


analogWrite(Channels[channel].GetPin(), Channels[channel].GetLightIntensityInt(now)); // Get updated light intensity and write value to pin (update is performed when reading value)

Będę wdzięczny za wskazówki

Pozdrawiam

to są zwykłe wartości int (Integer):

1) w Channels[channel].GetPin() masz numer pinu danego kanału światła a w

2) Channels[channel].GetLightIntensityInt(now)) aktualny poziom świecenia danego kanału jako liczbę intege. - możesz ją wyświetlić za pomocą zwykłego Serial.print

Pozdrawiam

 

Edytowano przez FlyingDutch
  • Lubię! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.