Skocz do zawartości

slon

Użytkownicy
  • Zawartość

    121
  • Rejestracja

  • Ostatnio

Reputacja

82 Bardzo dobra

O slon

  • Ranga
    5/10

Informacje

  • Płeć
    Mężczyzna

Ostatnio na profilu byli

Blok z ostatnio odwiedzającymi jest wyłączony i nie jest wyświetlany innym użytkownikom.

  1. W folderze, który podałeś domyślnie instalują się wszystkie biblioteki, które pobierasz przez Arduino IDE. Jeśli sam pobierałeś biblioteki to też zapewne kopiowałeś je do tego folderu. Natomiast biblioteki jak np: Servo.h znajdziesz w katalogu C:\Program Files (x86)\Arduino\libraries. Może być też tak , że biblioteki są w folderze z projektem. Jeżeli chcesz zacząć z platform IO to tutaj jest fajny filmik.
  2. można odczytać wartość licznika w pętli głównej używając __HAL_TIM_GET_COUNTER np: int czas = __HAL_TIM_GET_COUNTER(&htim10); Możesz to zrobić postępują zgodnie z kursem dla F4 z tą różnicą , że po wykonaniu Kroku. 5 od razu generujesz projekt w CubeMX (nie konfigurujesz przerwań). W wygenerowanym projekcie przechodzisz do funkcji konfigurującej przerwanie TIM_Init i jako ostatnie polecenie dopisujesz : HAL_TIM_Base_Start(&htim10); Oczywiście konfigurację zegarów i timera możesz ustawić wedle własnych potrzeb. Nie jest to najbardziej optymalne rozwiązanie ale lepsze od HAL_Delay(). Nawiązując do Arduino a konkretnie płytek opartych o układy SAM/SAMD to wielozadaniowość jest możliwa z wykorzystanie delay() przykład.
  3. Dzięki za linki @FlyingDutch na pewno się przydadzą. Co do dokumentacji to na chwilę obecną korzystałem z informacji zawartych w SW4STM32 w zasadzie to te same opisy aczkolwiek user manual podaje więcej szczegółów.
  4. Ja ze swojej strony mogę się podzielić doświadczeniami związanymi z płytką Discovery F411 na której bazuje drugi kurs. Ogólnie ujmując to wszystko było by świetnie gdyby nie CubeMX. Idea graficznego wyklikiwania kodu sporo ułatwia ale też i utrudnia szczególnie na początku. Ja osobiście nie bardzo mogłem się w tym odnaleźć. Nie wspominając o wpisywaniu własnego kodu w odpowiednie miejsca w wygenerowanym projekcie (niby jest to zrozumiałe ale mi to nie pasowało). Efekt był taki , że płytka długo przeleżała w pudełku czekając na lepsze czasy :) Aż do niedawna kiedy to tak sobie otworzyłem kurs STM32 F1 niby to kurs dedykowany dla innej płytki ale bez CubeMX i opiera się głównie na SW4STM32 a ten już miałem zainstalowany. Wiec zacząłem jeszcze raz i to podejście o wiele bardzie mi pasuje dodatkowo zaopatrzyłem się w książkę : Programing with stm32 Getting started with the Nucleo. I puki co to nauka przebiega bardzo przyjemnie.
  5. takie drobne wprowadzenie do processing jest na forum tutaj. Podałem tam dwa przykłady a poniżej masz kolejny float theta = 0; void setup() { size(500,500); background(0); } void draw() { stroke(0); // sun in center translate(width/2, height/2); fill(255,200,50); ellipse(0,0,20,20); // earth rotates around the sun pushMatrix(); rotate(theta); translate(50,0); fill(50,200,255); ellipse(0,0,10,10); // moon 1 rotates around the earth pushMatrix(); rotate(-theta*4); translate(15,0); fill(50,255,200); ellipse(0,0,6,6); popMatrix(); // moon 2 rotates around the earth pushMatrix(); rotate(theta*2); translate(25,0); fill(50,255,200); ellipse(0,0,6,6); popMatrix(); popMatrix(); theta+=0.01; } a tak to wygląda w praktyce. W rzeczywistości animacja jest o wiele płynniejsza (draw() domyślnie "rysuj" 60 razy na sekunde). Processing jest o tyle ciekawy co do tworzenia efektów graficznych , że jak coś napiszesz nie tak jak powinno być to można dostać efekt inny od zamierzonego ale często bardzo ciekawy. Poniżej przykład kwadrat myKwadrat1; kwadrat myKwadrat2; kwadrat myKwadrat3; kwadrat myKwadrat4; float theta; void setup() { size(500,500); background(0); myKwadrat1 = new kwadrat(100,124,124); myKwadrat2 = new kwadrat(100,52,52); myKwadrat3 = new kwadrat(100,52,52); myKwadrat4 = new kwadrat(100,52,52); } void draw() { theta +=0.1; myKwadrat1.display(); myKwadrat2.display(); myKwadrat3.display(); myKwadrat4.display(); } class kwadrat { color c; int x; int y; //float theta; kwadrat (color tempC, int tempX, int tempY) { // float tempTheta) { c = tempC; x = tempX; y = tempY; //theta = tempTheta; } void display() { fill(c); translate(x,y); // Translate to the center //translate(width/2,height/2); rotate(theta); // Rotate by theta rect(0, 0, 52, 52); } } tak to wygląda w rzeczywistości tutaj moje założenie co do tego jak to miało wyglądać możesz zobaczyć w wiadomości, którą podlinkowałem na początku tematu.
  6. Pierwsza informacja pochodzi z "Arduino internals" strona 210/211 Accuracy.
  7. @atMegaTona w połowie tego filmu do pokoju wpadły dzieciaki i kazały mi to wyłączyć co też uczyniłem. Osobiście bardziej polecam serial "Czarnobyl" produkcji HBO.
  8. Któregoś dnia córka przyniosła ze szkoły karteczkę z linkiem scratch.mit.edu . Wcześniej tego nie widziałem i przyznam, że jest to ciekawa forma edukacji/programowania dla najmłodszych i nie tylko. Przypomina appinventora (bloczki) ale nie trzeba się logować i można ustawić język polski.
  9. Odnośnie arduino 16MHz quartz crystal +/- 100ppm czyli około +/- 4min na 30 dni (znaczenie ma też wiek kwarcu i temeratura). Ceramic resonator +/- 1% czyli jakieś 7 godzin na 30 dni. w moim wypadku moduł za 8.5zł nie spóźnił się nawet minuty przez rok użytkowania. Sprawdzałem też sekundy i wychodziło chyba 5 sekund ale nie jestem do końca pewien. I na koniec zegarek Casio MTP-1290. Przed zakupem sprawdzałem w katalogu casio jakie są rozbieżności w czasie dla różnych modeli i ten model miał jedne z najniższych nawet w porównaniu do zegarków dwa razy droższych. W nocie jak dobrze pamiętam było 20 sekund na 3 miesiące. Zegarek mam od 3 lat i z reguły przestawiam go raz na rok przy zmianie czasu ale żeby miał więcej jak 2 minuty rozbieżności to nie zauważyłem.
  10. @Treker jeśli brać by tylko pod uwagę ten jeden punkt : 2) Develop a low-cost, low-powered soil sensing architecture: current precision agriculture solutions are expensive and out-of-reach to many farmers in the developing world. To zastosowanie na pewno by się znalazło. Natomiast co do GMO to jeszcze za czasów moich studiów obowiązek zamieszczania informacji na etykiecie produktu występował jeśli zawartość GMO przekraczała 5% poniżej tej wartości nie było takiego obowiązku. Obecnie dochodzi do tego , że forsowany jest projekt w , którym informacja o GMO w składzie produktu miała by nie być wymagana. Wyjątkiem miały by być produkty pochodzące z gospodarstw ekologicznych aczkolwiek w tym wypadku należało by rozgraniczyć produkty , które posiadają certyfikat gospodarstwa ekologicznego od wszelkiej maści produktów eko bio itp. Swoją drogą w ubiegłym miesiącu o ile dobrze pamiętam można było się wpisać do ankiety , w której można było wyrazić swój sprzeciw wobec takich praktyk. Osobiście nie jestem zwolennikiem GMO.
  11. Jak zobaczyłem jedno z tych zdjęć to przypomniały mi się zajęcia z gleboznawstwa
  12. @Treker i o to mi chodziło. Sądziłem , że tego właśnie się tyczy to drugie pytanie (zostało wydzielone od pierwszego) jeśli miało być inaczej to faktycznie mój błąd.
  13. Wersja alternatywna z wykorzystaniem timer1 do odmierzania czasu. Rozmiar szkicu zmniejszony do 5%. volatile uint8_t count; volatile uint8_t countBuf; uint8_t timerSeconds; uint8_t timerSecondsBuf; uint8_t score; uint16_t timer1; uint16_t ledCounter; #define BAUD_RATE 9600 #define BAUD_RATE_DIVISOR (F_CPU / 16 / BAUD_RATE - 1) void setup() { UCSR0A = 0 << TXC0 | 0 << U2X0 | 0 << MPCM0; UCSR0B = 0 << RXCIE0 | 0 << TXCIE0 | 0 << UDRIE0 | 0 << RXEN0 | 1 << TXEN0 | 0 << UCSZ02 | 0 << TXB80; UCSR0C = 0 << UMSEL01 | 0 << UMSEL00 | 0 << UPM01 | 0 << UPM00 | 0 << USBS0 | 1 << UCSZ01 | 1 << UCSZ00 | 0 << UCPOL0; UBRR0 = BAUD_RATE_DIVISOR; DDRC = 15; // A0..A3 Output DDRB = 48; //D8...D11 INPUT, D12 and D13 Output PORTB = 15; //D8...D11 High impedance DDRD = 60; //D2...D5 OUTPUT PORTD = 192; //D6 D7 High impedance PCICR = 5; // enable pin change interrupt bank 0 and 2 PCMSK0 = 15; //enable pin change interrupt PCINT0...PCINT3/D8...D11 PCMSK2 = 192; // enable pin change interrupt PCINT22/D6 D7 TCCR1A = 0; TCCR1B = 1 << WGM13 | 1 << WGM12 | 1 << CS12 | 1 << CS10; //prescaler set to 1024 TIMSK1 = 32; // enable capture event interrupt ICR1 = 15625; //input capture register 1s } void loop() { start(timeSet(2, 0, 0), timeSet(1, 0, 0), timeSet(1, 0, 0), 170); } ISR(TIMER1_CAPT_vect) { if (count == 255) { countBuf = 0; count = 0; } count++; timerSeconds++; if (!timerSeconds) timerSecondsBuf++; } ISR(PCINT0_vect) { for (uint8_t i = 0; i < 4; i++) { if (bitRead(PINB, i) == 0 && bitRead(PIND, 2 + i) == 1) { bitClear(PORTD, 2 + i); score++; } } } ISR(PCINT2_vect) { for (uint8_t i = 0; i < 2; i++) { if (bitRead(PIND, i + 6) == 0 && bitRead(PINB, i + 4) == 1) { bitClear(PORTB, i + 4); score++; } } } void results() { if (ledCounter - score > 0 && ledCounter - score < 5 ) bitSet(PORTC, (ledCounter - score) - 1); } void start(uint16_t wait, uint16_t onTime, uint16_t offTime, uint16_t counter) { static uint8_t index = 0; uint8_t pin[30] = {3, 4, 12, 2, 4, 13, 3, 2, 2, 4, 5, 13, 3, 5, 3, 5, 3, 4, 4, 3, 5, 3, 2, 3, 4, 2, 12, 12, 3, 2}; for (countBuf; countBuf < count; countBuf++) { timer1 = timerSeconds + (timerSecondsBuf * 256); //printi(timer1); printc('\n'); if (timer1 == wait + 1 && ledCounter <= (counter - 1)) { (pin[index] == 12 || pin[index] == 13) ? PORTB |= 1UL << (pin[index] - 8) : PORTD |= 1UL << pin[index]; ledCounter++; //printi(ledCounter); printc('\n'); } else if (timer1 == wait + 1 + onTime) { (pin[index] == 12 || pin[index] == 13) ? PORTB &= ~(1UL << (pin[index] - 8)) : PORTD &= ~(1UL << (pin[index])); results(); printi(score); printc('\n'); } if (timer1 == wait + onTime + offTime) { index++; if (index == 30) index = 0; timerSeconds = wait; //if (ledCounter == 5) ICR1 = 3999; ledCounter < 34 ? ICR1 -= 233 : ICR1 -= 46; } else if (timer1 > wait + onTime + offTime) timerSeconds = 0; } } uint16_t timeSet(uint16_t s , uint16_t m , uint16_t h) { h = h * 3600; m = m * 60; return h + m + s; } void printc(char c) { loop_until_bit_is_set(UCSR0A, UDRE0); // wait for transmit buffer to be empty UDR0 = c; // transmit character out the serial port } void prints(char *s) { while (*s) { printc(*s); s++; } } void printi(long i) { char s[25]; // character buffer to build string in itoa(i, s, 10); // convert integer to ASCII string, base 10 prints(s); // now print the string on the serial port } Rozgrywka nie kończy się po zapaleniu 4 diod a trwa dalej aż do 170 mignięć. Wartości poniżej jednej sekundy można uzyskać modyfikując rejestr ICR1 np: dajemy w komentarz tą linijkę //ledCounter < 34 ? ICR1 -= 233 : ICR1 -= 46; i tą //printi(score); printc('\n'); odznaczamy komentarz w tej linijce if (ledCounter == 5) ICR1 = 3999; i tej printi(timer1); printc('\n'); wartości dla funkcji start ustawiamy np: start(timeSet(15, 0, 0), timeSet(6, 0, 0), timeSet(2, 0, 0), 20); z takimi zmianami szkic można wgrać do arduino i otworzyć serial monitor. Po piętnastu sekundach diody zaczynają się zmieniać i po 5 mignięciach zostaje ustawiona wartość dla rejestru ICR1 na 3999 czyli 256 ms i co tyle jest aktualizowana zmienna timer1. Natomiast czas włączenia będzie wynosił 256ms * 6 = 1536ms i czas wyłączenia 2*256=512ms. Czas można też spowolnić ustawiając wartość dla rejestru ICR1 np na 62499 czyli 4s. W takim wypadku zmienna timer1 będzie aktualizowana co 4s , włączenie 6*4 =24s i wyłączenie 6*2=12s. Co do samych wartości dla rejestru ICR1 to można pobrać darmową aplikację z google play AVR Calculator w, której wystarczy podać kilka parametrów (w tym wypadku procesor 16MHz, timer 16 bit, Prescaler 1024 i podać czas jaki nas interesuje lub częstotliwość i kliknąć calculate). Ten kod nie działa w simulIDE trzeba wgrywać do prawdziwego arduino :).
  14. Skoro już jesteśmy przy Atmel Studio to opiszę coś pożytecznego czyli: jak przesiąść się z Arduino IDE na Atmel Studio . W tym celu użyłem: Arduino IDE 1.8.2 , Atmel Studio 7.0 zainstalowane w katalogach domyślnych. Arduino Nano (klon). Na początek otwieramy Arduino IDE tworzymy nowy (pusty) projekt o nazwie np: Arduino. W ustawieniach Arduino IDE zaznaczamy opcję upload (jest podkreślona na obrazku) i wgrywamy do naszego arduino (u mnie jest to nano). To co nas będzie interesowało to port COM oraz Overriding Baud Rate. Teraz instalujemy Atmel Studio 7.0 Po zainstalowaniu AS7 wybieramy Tools i kolejno External tools. Tutaj mamy trzy pozycje do uzupełnienie: Title: proponuje zostawić tak jak jest Command: wklejamy to co poniżej C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude.exe Arguments: tutaj trzeba uwzględnić numer portu COM oraz Overriding Baud Rate tak jak na pierwszym obrazku z Arduino IDE. Tu się zgada więc nie muszę tego zmieniać. Jeśli będzie inaczej to po wklejeniu do AS trzeba sobie te wartości odpowiednio ustawić. -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -carduino -PCOM7 -b57600 -D -Uflash:w:"$(ProjectDir)Debug\$(TargetName).hex":i Na koniec Zaznaczamy jeszcze: Use output window. W tym momencie mamy skonfigurowany AS7 do pracy z arduino. Tworzymy więc pierwszy projekt oparty na szkicu Arduino IDE. Wybieramy kolejno File , New project , wybieramy ostatnią pozycję i zatwierdzamy. tutaj kolejno wybieramy ścieżkę do pliku arduino, który stworzyliśmy w pierwszym etapie oraz rodzaj płytki i zatwierdzamy. teraz w zasadzie można tylko uzupełnić setup() i loop() o np: kod blinka. Kolorowanie składni oraz autouzupełnianie działa wiec będzie to bardzo proste. Następnie wybieramy Build Solution i sprawdzamy czy kompilator nie zgłosił żadnych błędów. Następnie przechodzimy do zakładki tools i wybieramy Arduino_via_bootloader (taki tytuł nadaliśmy). Jeśli cały proces przebiegł poprawnie to będziemy mieli arduinowego blinka wgranego z poziomu AS7. Teraz ktoś mógł by powiedzieć ok ale ja chce pisać w sposób typowy dla AS a nie arduino. W tym celu postępujemy podobnie. file ---> new project , i opcja nr dwa. Następnie Wybieramy atmegę 328P i zatwierdzamy. tutaj przykładowy projekt ala blink z makrami bitSet i bitClear zaczerpniętymi a Arduino IDE. Wgrywamy w identyczny sposób jak w poprzednim przykładzie czyli Build ---> build Solution , tools--> Arduino_via_bootloader. W ten sposób mamy edytor ala mercedes ale bez opcji debuggowania. I na koniec jedna istotna uwaga. Część tego opisu można znaleść na YT (filmik trwa około 7min) ale nie jest to tak wyczerpująco opisane. Jeśli ktoś zauważy jakiś błąd to warto to zasygnalizować chociaż sprawdzałem kilka razy. Robiłem też test dla Arduino Uno. Działa bez problemu aczkolwiek w mim wypadku Overriding Baud Rate wynosił 115200 .
×
×
  • Utwórz nowe...