Servo se zpětnou vazbou 270°

Raspberry, Arduino, Mini-PC a další

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
pdp7
Příspěvky: 308
Registrován: 15 zář 2014, 00:00

Servo se zpětnou vazbou 270°

#1 Příspěvek od pdp7 »

Ahoj, omylem jsem koupil servo bez zpětný vazby DSS-M15S (dělají se 2 typy).
Snažil jsem se to tam dobastlit připojením čtvrtého drátu na běžec poťáku a čekal ve správnou funkci. Minimálně se podle aktuální polohy výstupní hřídele ono napětí mění od 0.3 - 3V. Na 500us puls je ta nejnižší hodnota napětí.
Pokud na to pustím jednoduchý program v IDE umožňující mi zadat polohu přes serial monitor vrací mi to na analogRead nesmyslný hodnoty. Očekával bych tam na nejmenší úhel nejmenší napětí a postupně až ke druhému konci dojezdu serva největší (a nebo opačně) ale není to tak! Vracejí se fakt kraviny.
Přílohy
servoDSS.ino.zip
(522 bajtů) Staženo 75 x
Uživatelský avatar
misocko
Příspěvky: 1528
Registrován: 26 čer 2009, 00:00
Bydliště: Hlohovec (Sk)

#2 Příspěvek od misocko »

začal by som pomeranim napetia ktoré sa realne vracia do Arduina. Ak je to skutočne 0,3 - 3 V a arduino nameria neičo ine, zjavne maš chybu v programe alebo zapojeni (napr neni spoločná zem)
kam to kurňa davate, aj mozila aj bitdefender mi hlasia problem...
čo tak použiť vlastný google disk?
Uživatelský avatar
Valdano
Příspěvky: 3117
Registrován: 01 led 2023, 00:00
Bydliště: Česká Lípa

#3 Příspěvek od Valdano »

V příkladu používáte při přepočtu na napětí referenční hodnotu 5V. Jakou desku Arduina konkrétně používáte a je to opravdu verze 5V a nebo je to verze 3.3V?
Uživatelský avatar
pdp7
Příspěvky: 308
Registrován: 15 zář 2014, 00:00

#4 Příspěvek od pdp7 »

Co hlásí problém, jako ten ino zdroják?
K tomu zapojení, jsou tam 4 dráty. napájení 5V, GND, PWM na D9, feedback na A0. Arduino je zapojené do PC přes USB, všechno.
Napětí do A0 jsem teď měřil na 1.5ms je cca 1.5V na 2.5ms 3V na 0.5ms je těch 0.3V.

Serial.print ukazuje něco jinýho. Viz. screen

Valdano: Arduino Nano a nevím co tam má být napsáno jestli 3.3 či 5V
Přílohy
screen.png
screen.png
Uživatelský avatar
Valdano
Příspěvky: 3117
Registrován: 01 led 2023, 00:00
Bydliště: Česká Lípa

#5 Příspěvek od Valdano »

pdp7 píše:Valdano: Arduino Nano a nevím co tam má být napsáno jestli 3.3 či 5V
To záleží na tom na jaké provozní napětí máte to Arduino Nano. Dělají se totiž s provozním napětím na 5V a také na 3,3V a každé má jinou referenci.

Pokud máte verzi pro 5V tak je správně

Kód: Vybrat vše

napeti = val * (5.0 / 1023.0);
Pokud máte verzi pro 3,3V tak by tam mělo být

Kód: Vybrat vše

napeti = val * (3.3 / 1023.0);
Uživatelský avatar
Valdano
Příspěvky: 3117
Registrován: 01 led 2023, 00:00
Bydliště: Česká Lípa

#6 Příspěvek od Valdano »

Zkuste to takto.

Kód: Vybrat vše

#include <Servo.h>
Servo myServo;
int pos,val;
float napeti;
double dat;
unsigned long cas;

void setup()
{
  Serial.begin(9600);
  myServo.attach(9);
  myServo.write(0);
  cas = millis();
}

void loop()
{
  Serial.println("Enter position: ");
  if (Serial.available() > 0) {
    pos = Serial.readString().toInt();
    if (pos >= 0 && pos <= 180){
      myServo.write(pos);
      Serial.print("Turned to: ");
      Serial.println(pos);
    } else {
      Serial.println("Invalid postition!");
    }
  }
  if ((millis() - cas) > 10000 {
    val = analogRead(A0);
    napeti = val * (5.0 / 1023.0);
    Serial.print("Feedback: ");
    Serial.print(napeti);
    Serial.println("V");
    dat = (double)val * 0.47 - 33.4;
    Serial.print("Uhel: ");
    Serial.print(dat);
    Serial.println("°");
  }
}
Možná by to chtělo mrknout na ten pin A0 osciloskopem jestli to napětí na něm nějak výrazněji nekolísá. Měřák to nemusí zachytit.
Naposledy upravil(a) Valdano dne 26 říj 2025, 21:05, celkem upraveno 1 x.
Uživatelský avatar
pdp7
Příspěvky: 308
Registrován: 15 zář 2014, 00:00

#7 Příspěvek od pdp7 »

OK. Ale myslím si že to nefachá :roll:
S tím osciloskopem si to myslím taky, že tam asi není uplně průběh takový jaký by měl být, a zdroj problému je moje vidlácká úprava serva. :lol:
Přílohy
screen2.png
screen2.png
Uživatelský avatar
bum
Příspěvky: 290
Registrován: 04 zář 2011, 00:00
Kontaktovat uživatele:

#8 Příspěvek od bum »

Úpravte si program tak aby načítal a zobrazoval pouze surovou hodnotu z pinu A0 při určitém zadaném úhlu a na dalším řádku pak vypočítanou hodnotu napětí podle vzorečku co tam je . Nic víc pro zjištění chyby nepotřebujete, vypadá to že možná zlobí potenciometr v servu pokud se budou hodnoty z potenciometru plynule měnit tak je v pořádku. Pak si ze surové hodnoty nebo i vypočítané hodnoty napětí podle toho vzorečku vypočítejte jaké dostanete stupně natočení. Osobně na přepočty používám programy jeden co mi umožňuje z vypočítané hodnoty zobrazit jaká surová načtená hodnota odpovídá této hodnotě a druhý pak co mi vypočítá ze surové hodnoty načtené analogovým vstupem Arduina napětí. Raději používám sériový terminál než terminál v IDE někdy jsou hodnoty jiné než je skutečnost vlastní zjištění, například při oživování robotického ramene kde mi zajímali hodnoty napětí na běžci potenciometru jednoho použitého nového serva nakonec byl vadný potenciometr z výroby. Uvedené programy jsou na webu.
Naposledy upravil(a) bum dne 26 říj 2025, 21:01, celkem upraveno 1 x.
Uživatelský avatar
Valdano
Příspěvky: 3117
Registrován: 01 led 2023, 00:00
Bydliště: Česká Lípa

#9 Příspěvek od Valdano »

Máte tam chybu. AnalogRead musíte číst mimo ten if opakovaně třeba jednou za vteřinu a nezávisle na té podmínce při nastavení pozice, protože ta proběhne jen jednou při zadání pozice přes serial monitor. Servu pak trvá nějakou dobu to přestavení na pozici, ale vy čtete AnalogRead hned poté, a to je příliš brzy a v tom je ten problém.

Zkuste to takto.

Kód: Vybrat vše

#include <Servo.h>

Servo myServo;
int pos,val;
float napeti;
double dat;
unsigned long cas;

void setup()
{
  Serial.begin(9600);
  myServo.attach(9);
  myServo.write(0);
  Serial.println("Enter position: ");
  cas = millis();
}

void loop()
{
  if (Serial.available() > 0) {
    pos = Serial.readString().toInt();
    if (pos >= 0 && pos <= 180) {
      myServo.write(pos);
      Serial.print("Turned to: ");
      Serial.println(pos);
    } else {
      Serial.println("Invalid postition!");
    }
  }
  if ((millis() - cas) > 1000) {
    val = analogRead(A0);
    napeti = val * (5.0 / 1023.0);
    Serial.print("Feedback: ");
    Serial.print(napeti);
    Serial.println("V");
    dat = (double)val * 0.47 - 33.4;
    Serial.print("Uhel: ");
    Serial.print(dat);
    Serial.println("°");
    cas = millis();
  }
}
Naposledy upravil(a) Valdano dne 26 říj 2025, 21:13, celkem upraveno 1 x.
Uživatelský avatar
Celeron
Příspěvky: 20508
Registrován: 02 dub 2011, 00:00
Bydliště: Nový Bydžov

#10 Příspěvek od Celeron »

A proč to neuděláš klasicky, zpětnou vazbou z potenciomeru do servozesilovače serva? To v servu není úplnej klasickej servozesilovač? Pak stačí zadat jen mikrosekundy a o zbytek se postará knihovna.
Myslím, že odběr motoru serva dělá pulzní úbytky na napájení serva a proto ti to analogový napětí z potenciomeru kolísá.
Jirka

Proč mi nemůže všechno chodit hned ?!!
Uživatelský avatar
Valdano
Příspěvky: 3117
Registrován: 01 led 2023, 00:00
Bydliště: Česká Lípa

#11 Příspěvek od Valdano »

Tam nejde o kolísání napětí na vstupu A0, ale o to, že čte hodnotu napětí jen jednou při změně pozice a hned po zavolání myServo.write(pos); jenže to volání není blokující tj. nečeká až se pozice serva fyzicky nastaví na žádanou pozici. Tím, že hned poté zavolá AnalogRead() tak přečte hodnotu kdy je servo ještě v pohybu (přestavuje se na tu žádanou pozici) a tím mu chodí náhodné a nesmyslné hodnoty.

Když to udělá tak jak jsem upravil ten příklad naposledy výše tak by měl výslednou pozici vidět po chvíli správně až se servo na tu pozici nastaví tak by hodnota vrácená AnalogRead() měla odpovídat správné žádané poloze.
Naposledy upravil(a) Valdano dne 26 říj 2025, 21:25, celkem upraveno 1 x.
Uživatelský avatar
pdp7
Příspěvky: 308
Registrován: 15 zář 2014, 00:00

#12 Příspěvek od pdp7 »

Děkuji že se snažíte poradit, ale já furt nevím co je blbě. Vyhodil jsem výpis napětí a úhlu a dal tam jenom výpis hodnot z převodníku a nevypadá to moc funkčně.
Nikdy jsem v Arduinu (wiring) nedělal, tak se omlouvám, za lamí dotazy.
Kde mám vypisovat tu val proměnnou?
Přílohy
screen3.png
screen3.png
Uživatelský avatar
Valdano
Příspěvky: 3117
Registrován: 01 led 2023, 00:00
Bydliště: Česká Lípa

#13 Příspěvek od Valdano »

Pořád to máte špatně. AnalogRead() nesmíte volat hned po zavolání myServo.write(pos); protože to volání není blokující tj. nečeká až se pozice serva fyzicky nastaví na žádanou pozici. Tím, že hned po myServo.write(pos); zavoláte AnalogRead() tak přečte hodnotu kdy je servo ještě v pohybu (přestavuje se na tu žádanou pozici) a tím vám chodí náhodné a nesmyslné hodnoty.

Udělejte to přesně takto viz níže.

Kód: Vybrat vše

#include <Servo.h>

Servo myServo;
int pos,val;
float napeti;
double dat;
unsigned long cas;

void setup()
{
  Serial.begin(9600);
  myServo.attach(9);
  myServo.write(0);
  Serial.println("Enter position: ");
  cas = millis();
}

void loop()
{
  if (Serial.available() > 0) {
    pos = Serial.readString().toInt();
    if (pos >= 0 && pos <= 180) {
      myServo.write(pos);
      Serial.print("Turned to: ");
      Serial.println(pos);
    } else {
      Serial.println("Invalid postition!");
    }
  }
  if ((millis() - cas) > 1000) {
    val = analogRead(A0);
    napeti = val * (5.0 / 1023.0);
    Serial.print("Feedback: ");
    Serial.print(napeti);
    Serial.println("V");
    dat = (double)val * 0.47 - 33.4;
    Serial.print("Uhel: ");
    Serial.print(dat);
    Serial.println("°");
    cas = millis();
  }
}
Uživatelský avatar
pdp7
Příspěvky: 308
Registrován: 15 zář 2014, 00:00

#14 Příspěvek od pdp7 »

Ještě k tomu napíšu, stavěl jsem motoricky ovládaný kryt na dalekohled aby ho bylo možno ovládat na dálku z PC z jednoho návodu na Githubu

https://github.com/jlecomte/ascom-telescope-cover-v2

kde je to vpodstatě se vším všudy. Ale ono to nefunguje ani podle toho (s tímhle mým 🤐 servem).[/url]
Uživatelský avatar
pdp7
Příspěvky: 308
Registrován: 15 zář 2014, 00:00

#15 Příspěvek od pdp7 »

Valdano funguje. Teď ještě přijít na to proč se to servo nehejbe v případě toho krytu a ovládání ze seeeduina.
V PC seeeduino připojím, program pro ovládání observatoře ho vidí, ale servo si po kliknutí na otevřít jen tak tiše poťukává a jinak nic.
Na pinu PWM na osciloskopu vidím pulsy od 500-2500us, mosfet spíná studený konec napájení serva, ale funguje to divně, tak že gate budí jen při kliknutí na zavřít dekl. Podle mě to neví kde servo je a ve feedbacku je něco jinýho než u origo serva.
Odpovědět

Zpět na „Miniaturní počítače (Arduino, Raspberry a další)“