Почему эта программа работает на R3, но не работает на R4 Wifi?
Я работаю над этой программой уже несколько недель и наконец-то почти завершил её. Она загружается и, кажется, работает так, как мне нужно, на плате R3, но не запускается на моей плате R4 Wifi, хотя и сообщает об успешной загрузке.
Последовательный монитор ничего не показывает.
Думаю, дело в библиотеке DS1307, поскольку я пробовал заменить её на DS3232, что улучшило ситуацию, и программа запустилась. Но мне не удалось заставить плату считывать данные с часов реального времени (RTC). Я использую DS3231. Что может быть причиной проблемы?
#include <SolarPosition.h>
#include <DS1307RTC.h>
#define MOTOR_ON LOW
#define MOTOR_OFF HIGH
const uint8_t digits = 3;
//SolarPosition Home(134.898551, -25.539774); // Дом//КОД RTC
SolarPosition Home(32.898551, -2.539774); // Дом//КОД RTC
const int azEncoder_a = 2; // Зеленый - контакт 2 - цифровой
const int azEncoder_b = 4; // Белый - контакт 4 - цифровой
long azEncoder = 0;
const int elEncoder_a = 3; // Зеленый - контакт 3 - цифровой
const int elEncoder_b = 5; // Белый - контакт 5 - цифровой
long elEncoder = 0;
const int azLimitSwitchPin = A0; // ОПРЕДЕЛИТЬ ПИН ДЛЯ ИСПОЛЬЗОВАНИЯ В КАЧЕСТВЕ ОГРАНИЧИТЕЛЯ АЗИМУТА
const int elLimitSwitchPin = A1; // ОПРЕДЕЛИТЬ ПИН ДЛЯ ИСПОЛЬЗОВАНИЯ В КАЧЕСТВЕ ОГРАНИЧИТЕЛЯ АЗИМУТА
const int azMotorPinPositive = 12;
const int azMotorPinNegative = 11;
const int elMotorPinPositive = 10;
const int elMotorPinNegative = 9;
bool nightime;
bool daytime;
bool trackerAzimuthRunning = false;
bool trackerElevationRunning = false;
bool sunRising = false;
int azLimitSwitch = 0; // ПЕРЕМЕННАЯ ДЛЯ ХРАНЕНИЯ ВЫШЕУКАЗАННОГО ЗНАЧЕНИЯ
int elLimitSwitch = 0;
int hours;
int minutes;
int seconds;
int trackerAzimuthAngle;
int trackerElevationAngle;
int start = 0;
int azimuthSun_position;
float sunElevation;
float newPosition;
float oldPosition;
void setup() {
Serial.begin(9600);
pinMode(azEncoder_a, INPUT_PULLUP);
pinMode(azEncoder_b, INPUT_PULLUP);
pinMode(elEncoder_a, INPUT_PULLUP);
pinMode(elEncoder_b, INPUT_PULLUP);
attachInterrupt(0, azEncoderPinChangeA, RISING);
attachInterrupt(1, elEncoderPinChangeB, RISING);
pinMode(azLimitSwitchPin, INPUT); // КОНЦЕВОЙ ВЫКЛЮЧАТЕЛЬ
pinMode(elLimitSwitchPin, INPUT); // КОНЦЕВОЙ ВЫКЛЮЧАТЕЛЬ
pinMode(azMotorPinPositive, OUTPUT);
pinMode(azMotorPinNegative, OUTPUT);
pinMode(elMotorPinPositive, OUTPUT);
pinMode(elMotorPinNegative, OUTPUT);
SolarPosition::setTimeProvider(RTC.get);
}
void loop() {
rtcCode();
trackerAzimuthAngle = azEncoder / 1.67; //Это изменение в градусах
trackerElevationAngle = elEncoder / 1.67; // Это изменится на градусы
azLimitSwitch = digitalRead(azLimitSwitchPin);
elLimitSwitch = digitalRead(elLimitSwitchPin);
if (newPosition > oldPosition) {
Serial.print("Going Up");
Serial.print('\n');
sunRising = true;
}
else if (newPosition < oldPosition) {
Serial.print("Going Down");
Serial.print('\n');
sunRising = false;
}
oldPosition = newPosition;
newPosition = sunElevation;
Serial.print("AZIMUTH LIMIT SWITCH STATUS =....."); //0 = Закрыто
Serial.print(azLimitSwitch);
Serial.print('\n');
Serial.print("ELEVATION LIMIT SWITCH STATUS =....."); // 0 = Закрыто
Serial.print(elLimitSwitch);
Serial.print('\n');
if (start < 1) {
Serial.print("start ");
Serial.print(start);
Serial.print('\n');
homing(); // Этот оператор проверяет, была ли программа только что запущена.
}
Serial.print("TRACKER AZIMUTH ANGLE IS ");
Serial.print(trackerAzimuthAngle);
Serial.print('\n');
Serial.print("TRACKER ELEVATION ANGLE IS ");
Serial.print(trackerElevationAngle);
Serial.print('\n');
//КОРРЕКТИРУЙТЕ ЭТИ ВРЕМЕНА ДЛЯ ТЕСТИРОВАНИЯ
if (hours >= 2 && hours <= 21 && minutes <= 59 && seconds <= 59) {
daytime = true;
nightime = false;
} else {
nightime = true;
daytime = false;
}
Serial.print("DAYTIME ");
Serial.print(daytime);
Serial.print('\n');
Serial.print("NIGHTIME ");
Serial.print(nightime);
Serial.print('\n');
// ИЗМЕНИТЕ НИЖЕ ДЛЯ ТЕСТИРОВАНИЯ
if (daytime == true) {
azimuthRunning();
} else {
Serial.print("PAUSED NOT MOVING UNTIL 6AM");
Serial.print('\n');
digitalWrite(azMotorPinPositive, HIGH);
}
// ПРОВЕРЬТЕ, ПОРА ЛИ ВЕРНУТЬСЯ НА МЕСТО
if (hours == 9 && minutes == 18 && seconds == 0) {
homing();
}
delay(1000);
}
void homing() {
digitalWrite(azMotorPinNegative, MOTOR_OFF);
digitalWrite(azMotorPinPositive, MOTOR_OFF);
digitalWrite(elMotorPinNegative, MOTOR_OFF);
digitalWrite(elMotorPinPositive, MOTOR_OFF);
//АЗИМУТ НАВЕДЕНИЯ
while (digitalRead(azLimitSwitchPin) == LOW) {
Serial.print("HOMING AZIMUTH");
Serial.print('\n');
digitalWrite(azMotorPinNegative, MOTOR_ON);
}
digitalWrite(azMotorPinNegative, MOTOR_OFF);
while (digitalRead(azLimitSwitchPin) == HIGH) {
Serial.print("BACKING OFF AZIMUTH"); //Измените это, чтобы переместить двигатель
Serial.print('\n');
digitalWrite(azMotorPinPositive, MOTOR_ON);
azEncoder = 0; // Возвращает кодер в 0 после возврата в исходное положение
}
digitalWrite(azMotorPinPositive, MOTOR_OFF);
start++;
//УРОВЕНЬ НАВЕДЕНИЯ
while (digitalRead(elLimitSwitchPin) == LOW) {
Serial.print("HOMING ELEVATION");
Serial.print('\n');
digitalWrite(elMotorPinNegative, MOTOR_ON);
}
digitalWrite(elMotorPinNegative, MOTOR_OFF);
while (digitalRead(elLimitSwitchPin) == HIGH) {
Serial.print("BACKING OFF ELEVATION"); //Измените это, чтобы переместить двигатель
Serial.print('\n');
digitalWrite(elMotorPinPositive, MOTOR_ON);
elEncoder = 0; // Возвращает энкодер в 0 после возврата в исходное положение
}
digitalWrite(elMotorPinPositive, MOTOR_OFF);
start++;
}
void azimuthRunning() {
if (azimuthSun_position > trackerAzimuthAngle && daytime == true && trackerElevationRunning == false) {
trackerAzimuthRunning = true;
digitalWrite(azMotorPinPositive, MOTOR_ON);
Serial.print("AZ RUNNING ");
Serial.print('\n');
} else {
trackerAzimuthRunning = false;
digitalWrite(azMotorPinPositive, MOTOR_OFF);
Serial.print("AZ Waiting ");
Serial.print('\n');
}
if (trackerAzimuthRunning == false) {
elevationRunning(); //Elevation Running вызывается только если азимут не работает
}
}
void elevationRunning() {
if (sunRising == true) {
elevationUp();
} else if (sunRising == false) {
elevationDown();
}
}
void elevationUp() {
if (sunElevation > trackerElevationAngle && daytime == true) {
trackerElevationRunning = true;
digitalWrite(elMotorPinPositive, MOTOR_ON);
Serial.print("EL RUNNING GOING UP ");
Serial.print('\n');
}
else {
trackerElevationRunning = false;
digitalWrite(elMotorPinPositive, MOTOR_OFF);
Serial.print("EL GOING UP WAITING");
Serial.print('\n');
}
}
void elevationDown() {
if (sunElevation < trackerElevationAngle && daytime == true) {
trackerElevationRunning = true;
digitalWrite(elMotorPinNegative, MOTOR_ON);
Serial.print("EL RUNNING GOING DOWN ");
Serial.print('\n');
}
else {
trackerElevationRunning = false;
digitalWrite(elMotorPinNegative, MOTOR_OFF);
Serial.print("EL GOING DOWN WAITING");
Serial.print('\n');
}
}
void rtcCode() {
printTime(RTC.get());
Serial.print(F("Home:\t"));
printSolarPosition(Home.getSolarPosition(), digits);
Serial.println();
Serial.print('\n');
}
void azEncoderPinChangeA() {
azEncoder += digitalRead(azEncoder_a) == digitalRead(azEncoder_b) ? -1 : 1;
}
void elEncoderPinChangeB() {
elEncoder += digitalRead(elEncoder_a) == digitalRead(elEncoder_b) ? 1 : -1;
}
void printSolarPosition(SolarPosition_t pos, int numDigits) {
Serial.print(F("el: "));
Serial.print(pos.elevation, numDigits);
Serial.print(F(" deg\t"));
Serial.print(F("az: "));
Serial.print(pos.azimuth, numDigits);
Serial.println(F(" deg"));
azimuthSun_position = (pos.azimuth);
sunElevation = (pos.elevation);
}
void printTime(time_t t) {
tmElements_t someTime;
breakTime(t, someTime);
Serial.print(someTime.Hour);
Serial.print(F(":"));
Serial.print(someTime.Minute);
Serial.print(F(":"));
Serial.print(someTime.Second);
Serial.print(F(" UTC on "));
Serial.print(dayStr(someTime.Wday));
Serial.print(F(", "));
Serial.print(monthStr(someTime.Month));
Serial.print(F(" "));
Serial.print(someTime.Day);
Serial.print(F(", "));
Serial.println(tmYearToCalendar(someTime.Year));
hours = someTime.Hour;
minutes = someTime.Minute;
seconds = someTime.Second;
}
Код загружается и запускается с Wire.h в этой позиции, но не считывает данные из RTC.
#include <Wire.h>
#include <DS1307RTC.h>
#include <SolarPosition.h>
Если Wire.h находится в указанной ниже позиции, код загружается, но не запускается и не отображает ничего на последовательном мониторе.
#include <DS1307RTC.h>
#include <SolarPosition.h>
#include <Wire.h>
В любом случае добавление Wire.begin() не оказывает никакого влияния на вывод.
@user115219, 👍2
Обсуждение1 ответ
Я обнаружил, что добавление #include <Wire.h> в заголовок и Wire.begin() в файл настройки позволяет загрузить и запустить программу на плате R4 Wifi. Единственная проблема — не работают часы реального времени.
С тех пор я изменил библиотеку RTC на DS3232RTC.h и добавил <DS3232RTC myRTC> в заголовок. Я также изменил функции для получения и вывода RTC.
#include <DS3232RTC.h>
#include <SolarPosition.h>
DS3232RTC myRTC;
Void setup (){
SolarPosition::setTimeProvider(myRTC.get);}
void rtcCode() {
printTime(myRTC.get());}
Теперь программа работает так, как и ожидалось, и отображает время и дату точно.
Поздравляю с нахождением решения, но можно ли изучить вопрос подробнее, чтобы определить причину проблемы? Можете ли вы вернуться к проблеме (если сохранили код), а затем просто добавить строку #include<wire.h> и посмотреть, исправится ли ошибка с помощью include-файла или wire.begin()?, @Code Gorilla
Код загружается и работает с Wire.h в этой позиции, но не считывает данные из RTC., @user115219
- Преобразование в Unix Timestamp и обратно
- Разница между «time_t» и «DateTime»
- Создание таймера с использованием часов реального времени с указанием времени начала и остановки
- DS1307RTC Выводит загадочную дату 165/165/2165. Какие возможны исправления?
- Прямоугольный сигнал RTC
- RtcDateTime' не называет тип
- Библиотека времени Arduino и библиотеки RTC
- Не удалось выделить SSD1306 при добавлении константы
Какая часть кода вызывает проблему?, @jsotola
attachInterrupt(0, azEncoderPinChangeA, RISING);Не используйте здесь магические числа, вместо этого используйте digitalPinToInterrupt() для лучшей совместимости по типам плат. Какой вывод здесь вообще имеется в виду? То же самое относится и к другому оператору attachInterrupt()., @6v6gtПрерывания находятся на контактах 2 и 4. Я попробовал attachInterrupt(2 , azEncoderPinChangeA, RISING);, но энкодеры не заработали., @user115219
Я понятия не имею, какая часть программы вызывает проблему. На мониторе ничего не отображается., @user115219
Прерывания находятся на контактах 2 и 4. Я пробовал attachInterrupt(2 , azEncoderPinChangeA, RISING);2 — это не номер контакта, а номер прерывания. Попробуйте вместо этогоattachInterrupt(digitalPinToInterrupt(2) , azEncoderPinChangeA, RISING);. То же самое для контакта 4., @6v6gtИзвините, прерывания на 2 и 3. Я пробовал., @user115219
attachInterrupt(digitalPinToInterrupt(2), azEncoderPinChangeA, RISING); attachInterrupt(digitalPinToInterrupt(3), elEncoderPinChangeB, RISING);, @user115219
Попробую на R3 и посмотрю, заработают ли энкодеры., @user115219
Да, это отлично работает с R3. Но этот код не запускается на R4., @user115219
Я уже закомментировал весь код для кодировщиков, чтобы устранить эту проблему, но на R4 он все равно не работает., @user115219
В некоторых библиотеках DS1307 есть функция Wire.begin() в конструкторе, что может вызывать проблемы с некоторыми платами. Перенесите функцию Wire.begin() в setup() и попробуйте ещё раз. Если это не поможет, найдите простой пример кода для DS1307 или DS3231 и попробуйте сначала запустить его отдельно. Также убедитесь, что в IDE включены предупреждения компилятора., @6v6gt
Я изменил библиотеку RTC на DS3232RTC и исправил функцию получения времени из RTC, все загружается и работает отлично., @user115219
Хорошо, что проблема решена. Если вы можете продемонстрировать с помощью простого кода несовместимость конкретной библиотеки DS1307 с Uno R4 (но работающей с Uno R3), было бы неплохо ответить на свой вопрос, указав точную версию библиотеки. Это может помочь и другим., @6v6gt