Arduino Polska Forum

Pełna wersja: JAK to się robi ...
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Stron: 1 2
Sprawa  wygląda  tak  kod  z  internetu sterowanie  hdd z ardrino u mnie UNO  oczywiście  działa  ...
https://www.youtube.com/watch?v=CMz2DYpos8w

"lekko zmodyfikowany idea jak w oryginale " jest  to "szybki kod  w pętli " przełączający cewki o 120 
i chciałem w ramach Nuki-experymentu  podkraść/podejrzeć zmienna co 1s z zastosowaniem mils() i wyświetlić na  oled i mam problem ...(w   zasadzie chciałbym co 0,5 s)
dodanie  kodu wyświetlania  na  oled  lub na  serialu spowalnia pętlę co doprowadza do szarpania silnika ...
JAK się takie zadanie realizuje ...
W głównej pętli wykonuje  się coraz szybszy  rozpędzający kod  do punktu stabilizacji a tu poboczne  zadanie psuje pracę ....  NIE WIEM JAK WSTAWIC KOD sory robie jak umie ....(prosił bym o link jak to zrobic )

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

int phase1 = 2;
int phase2 = 3;
int phase3 = 4;
int led1 = 10;
int led2 = 12;
int led3 = 13;
int steps = 5;
unsigned long MaxKrok   = 40000;
unsigned long MinKrok = 1200;
unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzas= 0;

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 
  display.setTextColor(WHITE); 
    pinMode(led1, OUTPUT);  
    pinMode(led2, OUTPUT);
    pinMode(led3, OUTPUT);
    pinMode(phase1, OUTPUT);
    pinMode(phase2, OUTPUT);
    pinMode(phase3, OUTPUT);
    digitalWrite(led1, LOW); 
    digitalWrite(led2, LOW); 
    digitalWrite(led3, LOW); 
}

void loop() {

  switchStep(1);
  switchStep(2); 
  switchStep(3);
 
   if(MaxKrok > MinKrok)   //kroki potrzebne  do przyspieszenia  silnika
  {
    MaxKrok = MaxKrok - steps;
  } else {
    MaxKrok=MinKrok;
  }
 if (MaxKrok < 39950 && MaxKrok > 20000) { digitalWrite(led1, HIGH); steps = 300; } else digitalWrite(led1, LOW);
 if (MaxKrok < 20000 && MaxKrok > 3000 ) { digitalWrite(led2, HIGH); steps = 50 ;} else digitalWrite (led2 , LOW);
 if (MaxKrok < 3000 && MaxKrok > MinKrok ) { digitalWrite(led3, HIGH); steps = 2 ;} else digitalWrite (led3 , LOW);

// podkradniecie zmiennej MaxKrok co 1s z petli glownej i do oled
aktualnyCzas = millis();
   if (aktualnyCzas - zapamietanyCzas >= 1000)
    {
    display.clearDisplay();
    display.setCursor(8,10);
    display.println(MaxKrok);
    display.display();
    zapamietanyCzas = aktualnyCzas;
  }
}

void switchStep(int stage) // zmiana  faz
{
  switch(stage)
  {
  case 1:
    digitalWrite(phase1, HIGH);
    digitalWrite(phase2, LOW);
    digitalWrite(phase3, LOW);
    myDelay(MaxKrok);
    break;
    
  case 2:
    digitalWrite(phase1, LOW);
    digitalWrite(phase2, HIGH);
    digitalWrite(phase3, LOW);
    myDelay(MaxKrok);
    break;
    
  default:
    digitalWrite(phase1, LOW);
    digitalWrite(phase2, LOW);
    digitalWrite(phase3, HIGH);
    myDelay(MaxKrok);
    break;
  }  
}
void myDelay(unsigned long p) {
if (p > 16380) {
  delay (p/1000);
  } else {
  delayMicroseconds(p);
  }
}

POZDRAWIAM  DZIEKI
Powiem tak, nie tylko "dodanie kodu wyświetlania na oled lub na serialu spowalnia pętlę", ale te delaye również.
Kod jest tak napisany, żeby obsługiwał tylko ten silnik i nic więcej, poprzez dobrany, podejrzewam, że eksperymentalnie, ten delay.
Na początku funkcji loop() jest trzy razy wywołana funkcja switchStep(), w które są delaye. Jeśli już umiesz wykorzystywać millis, to pozbądź się delay i wywołują tę sekwencję
switchStep(1);
switchStep(2);
switchStep(3);
z warunkiem od millis porównywanym z MaxKrok.
Napisz po polsku to może ktoś zrozumie i odpisze.
(25-04-2019, 19:53)kaczakat napisał(a): [ -> ]Napisz po polsku to może ktoś zrozumie i odpisze.
A czemu nie odpisałeś tak, jak to ostatnio robisz a wcześniej za to mnie ganiłeś, czyli:
- Kurs Arduino
- Kurs C/C++
- Kurs elektroniki

Autorowi postu mogę podpowiedzieć, użyłeś
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Zobacz co tam jest i wszystko stanie się jasne.
Cześć 
Nic  z waszych odpowiedzi nie  rozumie  ....
1) wiem że  biblioteki są "wypchane" i że spowalniają ... pętle
2) Kod był zaprojektowany dla konkretnego silnika i delay jest  dobrany 
zasadniczo nic nie zmieni czy użyje milis  czy delay ideom programu jest wstrzymywanie (może  było by troche wiecej czasu dla wyświetlacza )... przy przełączaniu faz oba  rozwiązania są dobre , delay wstrzymuje  na tak krótki czas mikro sekundy że sądziłem ze nie powinno mieć to wpływu na  co 0,5  sekundowy odczyt  i wice wersa  (Ale  widze  że jeste  w  błędzie)  
3) Kod nie ma  komentarzy 
a) jest omówiony z  detalem na  filmie  sorry ...
b) to jest chyba  ze  100 lin tu nie ma co omawiać i kometować 

Ciekaw  jestem czyli te  wszystkie szybkie kody z  wyświetlaczami które coś robią i zwracają  to na  ekran mają  specjalnie  pisane  albo pocięte  biblioteki dla  wyświetlaczy  ?
(26-04-2019, 12:54)maniek100 napisał(a): [ -> ]2) Kod był zaprojektowany dla konkretnego silnika i delay jest  dobrany 
zasadniczo nic nie zmieni czy użyje milis  czy delay ideom programu jest wstrzymywanie (...)
Ideom?
Silnik powinien sterować sprzęt (np timer) jak czasy są długie można robić to w przerwaniach. Nie robi się takich rzeczy w pętli głównej.

(26-04-2019, 12:54)maniek100 napisał(a): [ -> ]a) jest omówiony z detalem na filmie sorry ...
Sorry ale ja i wiele innych osób nie ma ochoty oglądać filmów.

(26-04-2019, 12:54)maniek100 napisał(a): [ -> ]b) to jest chyba ze 100 lin tu nie ma co omawiać i kometować
Skoro tak uważasz to masz problem.
Podpisuję się obiema rękami i nogami pod wypowiedzią ES2.
Jeśli w tym projekcie jest delay(), to jet on tylko demem, pokazującym, że można taki silnik wysterować bez Halla, lub bez pomiarów SEM.
Po pierwsze: jeśli chcesz rozbudować ten kod, to pozbądź się delay()
Po drugie: ten silnik z jakimkolwiek obciążeniem nie będzie się kręcił na tym kodzie.
Sterowniki silników bezszczotkowych mierzą siłę elektromotoryczną indukowaną na cewkach, dzięki czemu są w stanie określić położenie wału bez korzystania z czujników Halla.
Muszę Cię zmartwić. Programowanie mikroprocesorów, to nie łatwa sztuka. I na pewno nie osiąga się zadowalających efektów w krótkim czasie, do tego opierając swoją wiedzę i doświadczenie na filmach z jutuba.
(25-04-2019, 21:50)es2 napisał(a): [ -> ]
(25-04-2019, 19:53)kaczakat napisał(a): [ -> ]Napisz po polsku to może ktoś zrozumie i odpisze.
A czemu nie odpisałeś tak, jak to ostatnio robisz a wcześniej za to mnie ganiłeś, czyli:
- Kurs Arduino
- Kurs C/C++
- Kurs elektroniki

Autorowi postu mogę podpowiedzieć, użyłeś
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Zobacz co tam jest i wszystko stanie się jasne.

Strasznie Pan ciekawski, nie przypominam sobie bym tylko ostatnio polecał komuś, kto nic "nie trybi" w temacie kurs Arduino, robię to od zawsze. W tym wypadku nawet nie chciało mi się go wkleić, bo nie wiem co napisał.  A jeśli komuś przeedytowałem post i zniknęły głupie literówki to i ich cytowanie straciło sens.  Niestety tu na forum nie ma kosza by tam przenieść post z wyjaśnieniami. Dzięki czemu takimi pytaniami i odpowiedziami będzie się robił śmietnik w każdym temacie. Na szczęście nic tu ciekawego i tak nie było.
BARDZO WSZYSTKICH PRZEPRASZAM dajcie mi jeszcze jedną szanse ....

Aby zaprezentować problem napisałem 3 ledy zapalajace się jedna po drugiej na wyświetlacz trafia liczba która dioda jest aktualnie aktywna ...
Przejścia diod są uzależnione od milis 
Wyświetlacz podgląda zmienną co zadany czas która dioda świeci ("Procesy nie powinny kolidować")

1) Gdy uruchamiam bez wyświetlacza diody migają bardzo szybko
2) Gdy uruchamiam z wyświetlaczem diody spowalniają
3) Nastawiając różne czasy miedzy wyświetlaczem a czasem przejscia miedzy ledami widać że są zależności  są kombinacje które pokazują że podczas wyświetlania diody się na ułamek [s] wstrzymują przebieg nie jest płynny ...

Code

Kod:
//------------------ zdefiniowanie pinów --------------------------
#define ledPin2 2
#define ledPin3 3
#define ledPin4 4
#include "U8glib.h"                          //bibloteka  oleda
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);  

//------------------ ustawienia  stanow początkowych   ------------

unsigned long previousMillis2 = 0;
unsigned long previousMillis3 = 0;        
int ledState2 = HIGH;  
int ledState3 = HIGH;  
int ledState4 = HIGH;
int flaga2 = 0;    
//-----------------------inicjaizacje------------------------------    
void setup()
{
Serial.begin(9600);
u8g.setFont(u8g_font_unifont);        // dla wyswietlacza
pinMode(ledPin2, OUTPUT);            //LEDY ....
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
}

void loop(){
//--------------------- pierwsza dioda  wszeregu trzech się zapala --------------------------------------------                                            
 unsigned long Millis2 = millis();           //wczytanie MILLIS startowego
  if ( (ledState2 == HIGH) &&(Millis2 - previousMillis2 >= 100))   // swiece LED... jesli mineło 500  wykonaj przebieg if-a  
 {  
   flaga2=1;                            // aktualna wartość dla wyswietlacza = Led ktory swieci
   ledState2 = LOW;                     //obecny  led off
   ledState3 = HIGH;                    //kolejny led on
// ledState4 = LOW;                     // niepotrzebna linia zostawiłem program pracuje  bez niej prawidłowo
   previousMillis2 = Millis2 ;          // przygotowanie milis  do nastepnego przejscia warunku  
   digitalWrite(ledPin2, ledState2);    // wczytanie stanow na wyjscia led
   digitalWrite(ledPin3, ledState3);    // wczytanie stanow na wyjscia led
// digitalWrite(ledPin4, ledState4);    // niepotrzebna linia zostawiłem program pracuje  bez niej prawidłowo                                          
 }
 //--------------------- druga dioda  wszeregu trzech się zapala -----------------------------------------
 if ( (ledState3 == HIGH) &&(Millis2 - previousMillis2 >= 100))                
 {
 flaga2=2;
   ledState3 = LOW;  
// ledState2 = LOW;
   ledState4 = HIGH;                                                          
   previousMillis2 = Millis2 ;               // opis  się powtarza inne ledy zapalane i gaszone
// digitalWrite(ledPin2, ledState2);  
   digitalWrite(ledPin3, ledState3);  
   digitalWrite(ledPin4, ledState4);                                            
 }
 //--------------------- trzecia dioda  wszeregu trzech się zapala --------------------------------------------
  if ( (ledState4 == HIGH) &&(Millis2 - previousMillis2 >= 100))                
 {
 flaga2=3;
   ledState2 = HIGH;
// ledState3 = LOW;  
   ledState4 = LOW;                          // opis  sie powtarza inne ledy zapalane i gaszone                                  
   previousMillis2 = Millis2 ;
   digitalWrite(ledPin2, ledState2);  
// digitalWrite(ledPin3, ledState3);    
   digitalWrite(ledPin4, ledState4);                            
 }
 //----------- obsługa wyswietlacza tu wyswietlam flaga2  z odrebnym czasem millis  ---------------------------------
 
  unsigned long Millis3 = millis();
  if (Millis3 - previousMillis3 >= 500)       // czas... co ile wczytuje na oled  inny niz przejscie miedzy ledami znacznie szybszy        
 {
     u8g.firstPage();          //typowa petla U8glib.h w ktorej musi wyswietlac się wartosc flaga2
 do {
     u8g.setPrintPos(10, 20);  //pozycja  an ekranie
     u8g.print(flaga2);        // liczba ktora dioda swieci = flaga 2
   } while( u8g.nextPage() );                                                  
     previousMillis3 = Millis3;  // kasowanie millis
   }  
}
//-----------------------------------------------

Kod nie ma żadnego znaczenia chodzi o zjawisko które tu występuje (czytanie zmiennej i wpisywanie na wyswietlacz i lagi za tym idące)
(02-05-2019, 19:43)maniek100 napisał(a): [ -> ]1) Gdy uruchamiam bez wyświetlacza diody migają bardzo szybko
2) Gdy uruchamiam z wyświetlaczem diody spowalniają
Proste jak kilometr sznurka w kieszenie, biblioteka obsługi LCD niepotrzebnie zużywa czas procesora. Szukaj innej / popraw tą co masz / zmień uC na taki z większym RAM i z DMA i, co oczywiste, wykorzystaj te możliwości.

LCD działa po I2C, użyj przerwań do transmisji, no i oczywiście bufora LCD (to zdaje się biblioteka robi). Z uzyciem przerwań, "równocześnie" będziesz czytał dane, obsługiwał UART, robił co tam jeszcze potrzeba i obsługiwał LCD. Bardziej skomplikowane rzeczy na AVR robiłem (emulacja slave 1-Wire Overdrive na IRQ, obsługa mostka USB po I2C lub SPI {nie pamiętam}, praca jako host 1-Wire {UART / DS2480 / DS2482} emulując VT-100 i coś tam jeszcze).
Trzeba wiedzieć, że wielowątkowość to duże zapotrzebowanie na RAM (nie tak duże jak RTOS ale 2kB to do dema wystarczą). Bufor na LCD (łatwo policzyć) na każdy USART, zarówno nadawanie jak i odbiór od kilkuset do kilku kB, na I2C podobnie. Do nowych projektów, bez kilkunastu/kilkudziesięciu kB nie podchodzę. Nie, że się nie da, da, ale zamiast 30 dni soft będę pisał 90 albo dłużej. Dalej zwykła matematyka, gdy produkcja jest w ilości 10szt na rok, lepiej aby była droższa a soft napiszę szybciej a taniej. Jeśli miliony miesięcznie, lepiej tani sprzęt, soft będzie drogi ale rozbije się na miliony szt.

Jak nie czujesz się na siłach napisać (zmodyfikować) obsługi LCD, uruchom RTOS. Lojalnie jednak ostrzegam, że trzeba poznać RTOS i pracę z systemami wielozadaniowymi. Mnie było łatwo, pisałem soft na Amigę, właściwie to PC. Amiga to też PC, tak jaki np MAC i dziesiątki konstrukcji lepszych od ówczesnego IBM, który w tamtych czasach mógł pomarzyć o wielozadaniowości na swoim 8086 z DOS (co nie znaczy, ze systemów, prawdziwych wielozadaniowych a nie jak nakładka na DOS Win3.11 albo udawany wielozadaniowy Win95) na 8086 nie było. Były nawet PRAWDZIWE! wielozadaniowe systemy na Z-80! Warto pamiętać, ze Windows, NADAL, nie jest prawdziwym systemem wielozadaniowym a Win95 była KŁAMLIWIE reklamowany jako pierwszy, prawdziwy, system wielozadaniowy. Po pierwsze, nie pierwszy, bo choćby MAC już dawno był, także Amiga, po drugie nie prawdziwy bo pewne operacje "blokowały" cały komputer! Temat na inną bajkę!.

Prawdopodobnie z RTOS wpakujesz się w jeszcze większe problemy, no i RTOS "lubi" RAM :-) RTOS bez RAM to jak Ferrari na polnej drodze.
Stron: 1 2