Právě že to bude měřit něco co není pravda a zašmodrchovaný to je právě tím že všichni honíte program ale vůbec se nezajímáte o to jak to je všechno zapojené a použité součástky. Ono ani někdo nemůže protože je závislý pouze na simulátorech bez nich je tam kde je. V analogových zapojeních jsme na použité součástky v sedmdesátých letech museli brát zřetel.
Plácáš nesmysly, když je tam napětí menší než je krok převodníku, tak prostě naměří 0 (nebo něco kolem nuly, když je tam šum), proč by měl naměřit něco jiného? A je úplně fuk, jaký má ten potenciometr odpor, za předpokladu, že vstupní odpor převodníku je řádově větší a to je určitě.
Už tu chybí jen "Já už jsem dělal blablabla, když ty jsi ještě tahala kačera."
Už jsme spolu měli hodně, hodně rozdílných názorů, no a ohledně kačera nevím proč bych měl tvrdit že já už dělal v elektronice když Vy jste tahala kačera, určitě jsem hodně starší než Vy ale tohle jsem nikdy o nikom netvrdil, tím bych tuto konverzaci ukončil. No s tím potenciometrem to bych neřešil, to by jsme se tady jenom osočovali a dohadovali o tom co je mi úplně ukradené. Ono jde o to že dnes vždy někdo něco stáhne z internetu a vůbec o tom nic neví a pak tápe a hlavně nezná funkci součástek a pouze slepě kopíruje zapojeni aniž by věděl co a jak a proč to tak je a další věci a to se týká i programů což je mi již zcela lhostejné.
Založen: Jan 01, 2023 Příspěvky: 2678 Bydliště: Česká Lípa
Zaslal: po říjen 27 2025, 23:24 Předmět:
pdp7 napsal(a):
Při kalibraci si to povrkávalo a nehejbalo (uplně stejně jako to co to dělalo doposud). Pak se ukázalo OK.
To je divné, protože s tím mnou upraveným programem se vám servo hýbe. Díval jsem se do toho Arduino_Firmware.ino, který jste tady přiložil.
Příkaz: COMMAND:COVER:CALIBRATE
Pokud je ve funkci loop() identifikován tento příkaz tak se volá funkce calibrateCover() a v ní se hned na začátku pošle na sériový port výpis
RESULT:COVER:CALIBRATE:OK
a až teprve poté se začíná provádět kalibrace. Takže ten výpis se vypíše vždy bez ohledu na stav provedení kalibrace.
Po tom výpisu se uvnitř calibrateCover() volá funkce powerUpServo(). Ve funkci powerUpServo() se na začátku volá digitalWrite(SERVO_SWITCH_PIN, HIGH) tj. zřejmě pin pro zapnutí napájení serva.
Na konci funkce powerUpServo() je chyba, protože se tam volá servo.write(pos) před voláním servo.attach(SERVO_CONTROL_PIN, 500, 2500) tj. v době kdy ještě není přiřazen pin pro řízení serva.
Toto je špatně.
kód:
servo.write(pos);
servo.attach(SERVO_CONTROL_PIN, 500, 2500);
return pos;
}
Opravil jsem to takto.
kód:
servo.attach(SERVO_CONTROL_PIN, 500, 2500);
servo.write(pos);
return pos;
}
Pak se ve funkci calibrateCover() provádí postupný posun serva v 18-ti krocích posunem o 10 od pozice 0 až do pozice 180. Do kalibrace jsem doplnil výpisy na serial monitor ať vidíte jednotlivé kroky viz níže.
Zkuste tedy tuto verzi.
kód:
#include <Servo.h>
#include <FlashStorage.h>
constexpr auto DEVICE_GUID = "55c7745e-d21a-43da-abc5-837adcb27344";
constexpr auto COMMAND_PING = "COMMAND:PING";
constexpr auto RESULT_PING = "RESULT:PING:OK:";
constexpr auto COMMAND_INFO = "COMMAND:INFO";
constexpr auto RESULT_INFO = "RESULT:DarkSkyGeek's Automated Telescope Cover And Spectral Calibrator Firmware v1.0";
constexpr auto COMMAND_COVER_OPEN = "COMMAND:COVER:OPEN";
constexpr auto RESULT_COVER_OPEN_OK = "RESULT:COVER:OPEN:OK";
constexpr auto RESULT_COVER_OPEN_NOK = "RESULT:COVER:OPEN:NOK";
constexpr auto COMMAND_COVER_CLOSE = "COMMAND:COVER:CLOSE";
constexpr auto RESULT_COVER_CLOSE_OK = "RESULT:COVER:CLOSE:OK";
constexpr auto RESULT_COVER_CLOSE_NOK = "RESULT:COVER:CLOSE:NOK";
constexpr auto COMMAND_COVER_CALIBRATE = "COMMAND:COVER:CALIBRATE";
constexpr auto RESULT_COVER_CALIBRATE_OK = "RESULT:COVER:CALIBRATE:OK";
constexpr auto COMMAND_COVER_GET_CALIBRATION = "COMMAND:COVER:GETCALIBRATION";
constexpr auto RESULT_COVER_GET_CALIBRATION = "RESULT:COVER:GETCALIBRATION:";
constexpr auto COMMAND_COVER_GETSTATE = "COMMAND:COVER:GETSTATE";
constexpr auto RESULT_COVER_STATE_OPENING = "RESULT:COVER:GETSTATE:OPENING";
constexpr auto RESULT_COVER_STATE_OPEN = "RESULT:COVER:GETSTATE:OPEN";
constexpr auto RESULT_COVER_STATE_CLOSING = "RESULT:COVER:GETSTATE:CLOSING";
constexpr auto RESULT_COVER_STATE_CLOSED = "RESULT:COVER:GETSTATE:CLOSED";
constexpr auto COMMAND_CALIBRATOR_ON = "COMMAND:CALIBRATOR:ON";
constexpr auto RESULT_CALIBRATOR_ON = "RESULT:CALIBRATOR:ON:OK";
constexpr auto COMMAND_CALIBRATOR_OFF = "COMMAND:CALIBRATOR:OFF";
constexpr auto RESULT_CALIBRATOR_OFF = "RESULT:CALIBRATOR:OFF:OK";
constexpr auto COMMAND_CALIBRATOR_GETSTATE = "COMMAND:CALIBRATOR:GETSTATE";
constexpr auto RESULT_CALIBRATOR_STATE_ON = "RESULT:CALIBRATOR:GETSTATE:ON";
constexpr auto RESULT_CALIBRATOR_STATE_OFF = "RESULT:CALIBRATOR:GETSTATE:OFF";
constexpr auto ERROR_INVALID_COMMAND = "ERROR:INVALID_COMMAND";
constexpr auto STR_OK = "OK";
constexpr auto STR_NOK = "NOK";
constexpr auto STR_SETUP_CALIB_DATA = "SETUP: data kalibrace ";
constexpr auto STR_SERVO_OFF = "Vypnuti napajeni serva";
constexpr auto STR_SERVO_ON = "Zapnuti napajeni serva";
constexpr auto STR_CALIBRATE_START = "Kalibrace: zacatek cyklu";
constexpr auto STR_CALIBRATE_END = "Kalibrace: konec cyklu";
constexpr auto STR_POINT = "Bod: ";
constexpr auto STR_SETPOS = "Presun serva na pozici: ";
constexpr auto STR_WAIT1S = "Cekani 1s...";
constexpr auto STR_SERVO_STAV = "Nacteny stav serva po presunu: ";
// Pins assignment. Change these depending on your exact wiring!
const unsigned int CALIBRATOR_SWITCH_PIN = 6;
const unsigned int SERVO_SWITCH_PIN = 7;
const unsigned int SERVO_FEEDBACK_PIN = 8;
const unsigned int SERVO_CONTROL_PIN = 9;
// Value used to determine whether the NVM (Non-Volatile Memory) was written,
// or we are just reading garbage...
const unsigned long NVM_MAGIC_NUMBER = 0x12345678;
// How long do we wait between each step in order to achieve the desired speed?
const unsigned long STEP_DELAY_MICROSEC = 30L * 1000; // 30 msec
// Variables used to move the servo in the main loop...
int servo_position = 0;
unsigned long last_step_time = 0;
void setup()
{
// Initialize serial port I/O.
Serial.begin(57600);
// Wait for serial port to connect. Required for native USB!
while (!Serial) { };
Serial.flush();
// Make sure the RX, TX, and built-in LEDs don't turn on, they are very bright!
// Even though the board is inside an enclosure, the light can be seen shining
// through the small opening for the USB connector! Unfortunately, it is not
// possible to turn off the power LED (green) in code...
pinMode(PIN_LED_TXL, INPUT);
pinMode(PIN_LED_RXL, INPUT);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
// Make sure the servo is initially de-energized...
digitalWrite(SERVO_SWITCH_PIN, LOW);
// Make sure the calibrator is initially turned off...
digitalWrite(CALIBRATOR_SWITCH_PIN, LOW);
calibratorState = off;
servo_position = 0;
last_step_time = 0L;
// When there is no calibration data yet, we have to assume that the cover is closed...
if (servoCalibrationData.magicNumber != NVM_MAGIC_NUMBER) {
coverState = closed;
} else {
// Close the cover, in case it is not completely closed.
// To make sure that `closeCover` does not have an undefined behavior,
// we initialize the `coverState` variable to `open`, just in case.
// That variable will be updated in the `closeCover` function,
// and then again once the cover has completely closed.
coverState = open;
closeCover(false);
}
}
void loop()
{
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n');
if (command == COMMAND_PING) {
handlePing();
} else if (command == COMMAND_INFO) {
sendFirmwareInfo();
} else if (command == COMMAND_COVER_GETSTATE) {
sendCurrentCoverState();
} else if (command == COMMAND_COVER_OPEN) {
openCover(true);
} else if (command == COMMAND_COVER_CLOSE) {
closeCover(true);
} else if (command == COMMAND_COVER_CALIBRATE) {
calibrateCover();
} else if (command == COMMAND_CALIBRATOR_GETSTATE) {
sendCurrentCalibratorState();
} else if (command == COMMAND_CALIBRATOR_ON) {
turnCalibratorOn();
} else if (command == COMMAND_CALIBRATOR_OFF) {
turnCalibratorOff();
} else if (command == COMMAND_COVER_GET_CALIBRATION) {
sendCalibrationData();
} else {
handleInvalidCommand();
}
}
// Blink the built-in LED to let the user know that the device needs to be calibrated once!
// Note: The device needs to be recalibrated every time the firmware is flashed.
if (servoCalibrationData.magicNumber != NVM_MAGIC_NUMBER) {
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
}
if (coverState == opening || coverState == closing) {
// Make sure we don't prematurely take a step if it's too early...
unsigned long now = micros();
if (now - last_step_time >= STEP_DELAY_MICROSEC) {
last_step_time = now;
if (coverState == opening) {
servo_position++;
if (servo_position >= 180) {
servo_position = 180;
coverState = open;
}
} else if (coverState == closing) {
servo_position--;
if (servo_position <= 0) {
servo_position = 0;
coverState = closed;
}
}
servo.write(servo_position);
if (coverState == open || coverState == closed) {
powerDownServo();
}
}
}
}
// Energize and attach servo.
int powerUpServo()
{
// Vypis zapnuti napajeni serva
Serial.println(STR_SERVO_ON);
digitalWrite(SERVO_SWITCH_PIN, HIGH);
// Default position (closed), which will be used only once,
// before we have successfully calibrated the servo.
int pos = 0;
if (servoCalibrationData.magicNumber == NVM_MAGIC_NUMBER) {
// Short delay, so that the servo has been fully initialized.
// Not 100% sure this is necessary, but it won't hurt.
delay(1000);
// Deal with slight errors in the calibration process...
if (pos < 0) {
pos = 0;
} else if (pos > 180) {
pos = 180;
}
}
// The optional min and max pulse width parameters are actually quite important
// and depend on the exact servo you are using. Without specifying them, you may
// not be able to use the full range of motion (270 degrees for this project)
servo.attach(SERVO_CONTROL_PIN, 500, 2500);
// This step is critical!
// Without it, the servo does not know its position,
// and the first write command will make it jerk to that position,
// which is what we want to avoid...
servo.write(pos);
return pos;
}
// Detach and de-energize servo to eliminate any possible sources of vibrations.
// Magnets will keep the cover in position, whether it is open or closed.
void powerDownServo()
{
// Vypis vypnuti napajeni serva
Serial.println(STR_SERVO_OFF);
servo.detach();
digitalWrite(SERVO_SWITCH_PIN, LOW);
}
// Function to calculate the mean of an array.
double mean(double arr[], int n)
{
double sum = 0.0;
for (int i = 0; i < n; i++) {
sum += arr[i];
}
return sum / n;
}
// Function to calculate the slope and intercept of a linear regression line.
void linearRegression(double x[], double y[], int n, double *slope, double *intercept)
{
double x_mean = mean(x, n);
double y_mean = mean(y, n);
double numerator = 0.0;
double denominator = 0.0;
for (int i = 0; i < n; i++) {
numerator += (x[i] - x_mean) * (y[i] - y_mean);
denominator += (x[i] - x_mean) * (x[i] - x_mean);
}
*slope = numerator / denominator;
*intercept = y_mean - (*slope * x_mean);
}
Na konci funkce powerUpServo() je chyba, protože se tam volá servo.write(pos) před voláním servo.attach(SERVO_CONTROL_PIN, 500, 2500) tj. v době kdy ještě není přiřazen pin pro řízení serva.
To není chyba, to je schválně je to tam i vysvětlený v komentáři. Po zavolání servo.attach() se servo nastaví do naposledy navolené pozice, proto ji nejdřív nastaví voláním servo.write(), aby servo zůstalo tam, kde je. Tak, jak jsi to přehodil, ztrácí celá zpětná vazba smysl.
Omlovám se všem, ale jak jsem napsal že si to popájím na broušáku (Danykův styl výroby DPS) tak jsem udělal a hádejte co. Funguje
Samozřejmně ještě popřemýšlím na tom odděleném silovém napájení serva (on ten dekl bude poměrně velký. Dalekohled je 300mm.
Časy uváděny v GMT + 1 hodina Jdi na stránku Předchozí1, 2, 3
Strana 3 z 3
Nemůžete odesílat nové téma do tohoto fóra. Nemůžete odpovídat na témata v tomto fóru. Nemůžete upravovat své příspěvky v tomto fóru. Nemůžete mazat své příspěvky v tomto fóru. Nemůžete hlasovat v tomto fóru. Nemůžete připojovat soubory k příspěvkům Můžete stahovat a prohlížet přiložené soubory
Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB.