Uwolnij swoje Arduino – programowanie Arduino bez bibliotek od Arduino

Uwolnij swoje arduino

Arduino – platforma programistyczna dla systemów wbudowanych opracowana w 2005 roku we Włoszech, oparta na Open Hardware. Celem projektu Arduino było stworzenie samowystarczalnej platformy umożliwiającej tworzenie projektów bez dodatkowych narzędzi. Obecnie Arduino dostarcza zarówno płytkę (np. Arduino Uno, z mikroprocesorem ATmega328P) jak i wieloplatformowe środowisko programistyczne tzw. Arduino IDE. Mikroprocesor umieszczony na płytce jest domyślnie wyposażony w bootloader który dostarcza możliwość programowania mikrokontrolera z wykorzystaniem portu szeregowego (UART). Jest to znaczne ułatwienie, dzięki temu aby zaprogramować mikroprocesor nie potrzebujemy zewnętrznego programatora.

Biblioteka Arduino

Arduino dostarcza również wysokopoziomową bibliotekę do kontrolowania peryferiów mikroprocesora. Użytkownik nie musi zatem zagłębiać się w wewnętrzną architekturę procesora, wystarczy umiejętność posługiwania się funkcjami dostarczonymi przez Arduino. Obecna wersja Arduino IDE nie daje użytkownikowi opcji rezygnacji z korzystania z wysokopoziomowej biblioteki.

Przykład realizacji prostego zadania (mruganie diody LED) z wykorzystaniem biblioteki Arduino:

int led = 13;
 
void setup() {                
	pinMode(led, OUTPUT);    
}
 
void loop() {
	digitalWrite(led, HIGH);
	delay(1000);
	digitalWrite(led, LOW);
	delay(1000);
}

Warto zwrócić uwagę, że powyższy kod nie zawiera definicji funkcji int main(). Funkcja ta jest zaimplementowana wewnątrz biblioteki Arduino:

int main(void)
{
	init();
 
#if defined(USBCON)
	USBDevice.attach();
#endif
 
	setup();
 
	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}
 
	return 0;
}

Widać wyraźnie, że zadaniem funkcji main() jest zainicjalizowanie biblioteki (uruchomienie funkcji init()), jednorazowe uruchomienie zdefiniowanej przez użytkownika funkcji setup() oraz nieskończone wykonywanie funkcji użytkownika loop().

A co z funkcją init()? Jej zadaniem jest konfiguracja timerów oraz ADC mikroprocesora. Funkcja ta dekonfiguruje również UART zainicjalizowany wcześniej przez bootloader.

Alternatywa – programowanie Arduino bez wysokopoziomowej biblioteki

Skąd w ogóle ten pomysł? Odpowiedź jest prosta. Ręczna konfiguracja peryferiów pozwala na lepsze zrozumienie zasad działania mikroprocesora. Zdobyta wiedza jest uniwersalna – umożliwia programowanie dowolnego mikroprocesora (nawet bardziej rozbudowanego np. ARM Cortex). Oczywiście zyskujemy również większą kontrolę nad sprzętem oraz szerokie pole do popisu jak chodzi o optymalizację.

Ile wart jest programista nierozumiejący urządzenia, które programuje?

Na powyższe pytanie odpowiedzieć powinien sobie każdy, kto poświęca swój czas na zrozumienie wysokopoziomowej biblioteki zamiast na zrozumienie urządzenia. Rzecz jasna nie jest to zawsze priorytetem danego projektu, w pewnych sytuacjach zagłębianie się w działanie mikroprocesora jest niewskazane (np. w przypadku kursów dla dzieci w wieku do 10 lat).

Do dzieła – przykład bez biblioteki Arduino

#include <avr/io.h>
#include <util/delay.h>
 
int main() {
	DDRB |= _BV(PB5);
	while (1) {
		PORTB ^= _BV(PB5);
		_delay_ms(1000);
	}
}

Powyższy kod realizuje dokładnie to samo zadanie, co ten wykorzystujący bibliotekę Arduino. Efektem wykonania kodu powinno być mruganie diody mieszonej na płytce Arduino UNO co jedną sekundę.

Kompilacja przykładu

Zakładając, że kod powyższego przykładu zapisaliśmy w pliku main.c, możemy użyć następującego polecenia:

avr-gcc -c -mmcu=atmega328p -Wall -Werror -Os -DF_CPU=16000000UL main.c -o main.o

Opis argumentów:

  • -c – tylko kompilacja, bez linkowania
  • -mmcu=atmega328p – model procesora docelowego (w przypadku Arduino UNO będzie to ATmega328p)
  • -Wall – włączenie raportowania wszystkich ostrzeżeń
  • -Werror – traktowanie wszystkich ostrzeżeń jako błędy (wymuszenie przerwania kompilacji w przypadku dowolnego ostrzeżenia)
  • -Os – włączenie optymalizacji pod kątem rozmiaru
  • -DF_CPU=16000000UL – definiujemy wymaganą stałą o nazwie F_CPU określającą taktowanie procesora w Hz. Przyrostek UL wymusza traktowanie liczby jako unsigned long (liczba 32bit bez znaku). Definicja ta jest wymagana do poprawnego działania pętli opóźniających realizowanych np. przez funkcje _delay_ms().
  • main.c – plik wejściowy
  • -o main.o – plik wyjściowy (skompilowany kod będzie umieszczony w pliku main.o)

Powyższe polecenie należy uruchomić dla każdego pliku ze źródłami projektu. W przypadku kompilacji plików napisanych w języku C++ zamiast avr-gcc należy użyć avr-g++.

Linkowanie

Do połączenia wszystkich plików projektu, w jeden plik „wykonywalny” należy użyć następującego polecenia:

avr-gcc -mmcu=atmega328p main.o -o main.elf

Proces linkowania polega na łączeniu plików obiektowych w jeden plik finalny ze wszystkimi danymi programu. Podczas tego procesu ustalane jest również ostateczne miejsce kodu oraz zmiennych w pamięci procesora. Jako pliki wejściowe należy podać wszystkie pliki obiektowe (*.o).

Nagrywanie programu

Przed nagraniem programu do pamięci mikroprocesora, musimy przekonwertować plik wynikowy w formacie ELF main.elf do formatu Intel Hex rozumianego przez program obsługujący programator. Można to zrobić następującym poleceniem:

avr-objcopy -O ihex -R .eeprom main.elf main.hex

Opis argumentów:

  • -O ihex – określamy format wyjściowy jako Intel Hex
  • -R .eeprom – usuwamy sekcje .eeprom (nie będziemy modyfikować pamięci EEPROM)
  • main.elf – plik wejściowy
  • main.hex – plik wyjściowy

Tak przygotowany plik main.hex nadaje się już do nagrania na procesor:

avrdude -p m328p -c arduino -b 115200 -P /dev/ttyACM0 -U flash:w:main.hex

Opis argumentów:

  • -p m328p – model procesora, który programujemy
  • -c arduino – typ programatora (korzystamy z protokołu bootloadera Arduino)
  • -b 115200 – baud rate interfejsu szeregowego (w przypadku bootloadera Arduino UNO jest to 115200 bodów)
  • -P /dev/ttyACM0 – ścieżka do urządzenia portu szeregowego (dokładną ścieżkę należy sprawdzić w logach jądra po podłączeniu Arduino do portu USB (np. wykonując polecenie dmesg))
  • -U flash:w:main.hex – aktualizujemy pamięć flash zapisując dane z pliku main.hex

Automatyzacja procesu kompilacji, linkowania i nagrywania

Cały proces możemy zautomatyzować wykorzystując narzędzie GNU/Make. W katalogu projektu należy utworzyć plik Makefile z następującą zawartością:

#
# Copyright (C) Patryk Jaworski <regalis@regalis.com.pl>
# 
# Makefile for Arduino projects wihout high-level library.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# 
 
# Makefile for Arduino UNO
 
AVRDUDE_UPLOAD_SPEED=115200
AVRDUDE_COM_PORT=/dev/ttyACM0
AVRDUDE_PROGRAMMER=arduino
AVRDUDE_MCU=m328p
 
MCU=atmega328p
CC_FLAGS=-Os -Wall -Werror -mmcu=$(MCU) -DF_CPU=$(F_CPU) -c
LD_FLAGS=-mmcu=$(MCU)
 
F_CPU=16000000UL
CC=avr-gcc
CXX=avr-g++
LD=avr-gcc
OBJ_COPY=avr-objcopy
 
OBJS=$(patsubst %.c, %.o, $(wildcard *.c))
 
main.elf: $(OBJS)
	$(LD) $(LD_FLAGS) $^ -o $@
 
main.hex: main.elf
	$(OBJ_COPY) -O ihex -R .eeprom $< $@
 
%.o: %.c
	$(CC) $(CC_FLAGS) $< -o $@
 
%.o: %.c %.h
	$(CC) $(CC_FLAGS) $< -o $@
 
%.o: %.cpp
	$(CXX) $(CC_FLAGS) $< -o $@
 
%.o: %.cpp %.h
	$(CXX) $(CC_FLAGS) $< -o $@
 
upload: main.hex
	avrdude -c $(AVRDUDE_PROGRAMMER) -p $(AVRDUDE_MCU) -b $(AVRDUDE_UPLOAD_SPEED) -P $(AVRDUDE_COM_PORT) -U flash:w:$<
 
clean:
	rm -rvf *.o main.elf main.hex
 
.PHONY: upload clean

Wykorzystując powyższy plik Makefile, kompilacja i nagranie programu na płytkę Arduino UNO sprowadza się do wykonania jednego polecenia (wewnątrz katalogu projektu):

$ make upload

To wszystko. Happy hacking!

Praktyczne przykłady wykorzystania środowiska tekstowego

Każdy użytkownik komputera w trakcie wykonywania codziennych czynności, takich jak sprawdzanie poczty, kopiowanie zdjęć z aparatu, tworzenie kopii zapasowych, napotyka na problemy, których rozwiązanie wydaje się być skomplikowane lub wymagać pewnego wyspecjalizowanego programu. Celem tego artykułu będzie pokazanie, że większość takich czynności da się wykonać bardzo prosto, szybko i sprawnie, korzystając z narzędzi oferowanych przez środowisko GNU/Linux.

Uwaga! Przykłady działają również w systemach Mac OS X (standardowo) oraz Windows (po doinstalowaniu np. Cygwina). Nie wszystkie :)

Nie jest to lista zebranych z Internetu przykładów, a napisane przeze mnie fragmenty, które uważam, że każdy powinien znać (nie tylko po to, żeby uprościć sobie życie, ale również ze względów bezpieczeństwa). Dla tych mniej świadomych – niektóre przykłady mogą być zaskakujące, ale działają!

Czytaj całość “Praktyczne przykłady wykorzystania środowiska tekstowego” »

Tajemnice wejścia/wyjścia – jak zrozumieć deskryptory plików, strumienie i potoki

Wstęp

Wielu początkujących programistów bardzo często ma problemy ze zrozumieniem i poprawnym zaimplementowaniem jednego z podstawowych elementów programu – systemu wejścia/wyjścia. Mowa rzecz jasna o środowisku tekstowym, w którym nie mamy do dyspozycji przycisków, pól tekstowych czy okienek dialogowych. O ile problem z początku może wydawać się banalny (z tego powodu większość wydaje się nie zwracać na niego uwagi) to na późniejszym etapie jego ignorowanie prowadzi do powstawania wielu absurdów.

W dalszej części postaram się rozwiać wszelkie wątpliwości na temat niżej wymienionych kwestii:

  • jak działa i czym jest wejście/wyjście programu,
  • jak ujednolicić obsługę wejścia/wyjścia w swoim programie:
    • jak umożliwić użytkownikowi programu podjęcie decyzji o sposobie wprowadzania danych (z klawiatury, z pliku a może z innego komputera?),
    • jak zminimalizować nakład pracy;

Zanim jednak przejdziemy do kwestii programowania, ważne jest, aby dobrze znać środowisko w którym będziemy uruchamiać programy. Poznanie środowiska ma kluczowe znaczenie w kwestii rozumienia wewnętrznej struktury programu, pozwala na głębsze myślenie na temat optymalizacji kodu, upraszcza testowanie i sprawia, że programy zyskają na jakości – staną się bardziej uniwersalne.

Czytaj całość “Tajemnice wejścia/wyjścia – jak zrozumieć deskryptory plików, strumienie i potoki” »

Nasza POsłanka przeciwko nam?

Będąc oburzony ostatnimi postępowaniami naszego Rządu postanowiłem skorzystać z prawa jakie mi **jeszcze przysługuje**, prawa do swobody wypowiedzi oraz wolności słowa.

Jako mieszkaniec Zawiercia, w dalszej części opiszę również moje spostrzeżenia na temat Anny Nemś, znanej i cenionej w naszym mieście Pani Poseł na Sejm.

Czytaj całość “Nasza POsłanka przeciwko nam?” »

Poczuj potęgę wolności z GNU/Linux

Poznaj GNU/Linux

GNU to darmowy, uniksopodobny system operacyjny złożony wyłącznie z wolnego oprogramowania (od angielskiego słowa freedom – wolność). GNU został zapoczatkowany we wrześniu 1983 roku przez Richarda Stallmana i stał się pierwszym projektem założonej przez niego dwa lata później Fundacji Wolnego Oprogramowania (ang. Free Software Foundation). Misją fundacji jest tworzenie, ochrona i promocja wolności użytkowania, kopiowania, modyfikowania i rozprowadzania programów komputerowych oraz obronę praw użytkowników Wolnego Oprogramowania. System GNU jest kompletny i samowystarczalny, oznacza to, że posiada wymagane do pracy i dalszego rozwoju opgrogramowanie, które jest całkowicie niezleżne.

Logo GNU

Czytaj całość “Poczuj potęgę wolności z GNU/Linux” »

Wprowadzenie do systemu kontroli wersji Git

Wprowadzenie

Artykuł ten przeznaczony jest dla osób, które potrafią zarządzać plikami w środowisku tekstowym, chdzi o umiejętność posługiwania się narzędziami do obsługi plików i katalogów takimi jak np. cd, ls, mv, mkdir, rm, rmdir. Jeżeli nie wiesz jak korzystać z tych programów – powinieneś zacząć od poszukania informacji na ich temat (nie powinno zająć to dłużej niż 5 minut). Brakuje motywacji? Przeczytaj jakie możliwości daje Git i zdecyduj czy Git Ci się przyda.

Mimo wszystko nie chcę nie potrafię obsługiwać tych narzędzi…

Istnieją przeróżne wtyczki do popularnych środowisk programistycznych i wiele narzędzi z graficznym interfejsem użytkownika, możesz z nich korzystać do nauki, jednak tylko praktyki zaprezentowane w tym artykule pozwolą w pełni zrozumieć mechanizm działania tego systemu kontroli wersji.

Podstawowe pojęcia

Zacznijmy od wprowadzenia podstawowych pojęć.

Repozytorium
ogólnie odnosi się do miejsca przechowywania i konserwowania dokumentów
Repozytorium lokalne
repozytorium, do którego mamy bezpośredni dostęp (np. znajduje się w na dysku twardym naszego komputera)
Repozytorium zdalne
repozytorium znajdujące się w sieci, aby uzyskać dostęp do takiego repozytorium niezbędne jest połączenie z hostem (komputerem) na którym znajdują się pliki (zazwyczaj wiąże się to z potrzebą posiadania dostępu do Internetu)
System kontroli wersji
narzędzie to śledzenia, indeksowania zmian w dokumentach. Umożliwia łączenie, przeglądanie zmian dokonanych przez różne osoby w różnych momentach

Czym jest Git?

Git logo

Git jest rozproszonym systemem kontroli wersji stworzonym przez Linusa Torvaldsa w 2005 roku. Każdy katalog kontrolowany przez Git jest w pełni funkcjonalnym repozytorium. Oznacza to, że aby korzystać z repozytorium nie jest wymagane połącznie z głownym serwerem, zawsze mamy dostęp do pełnej historii zmian wszystkich plików. Git jest wolnym oprogramowaniem (jest całkowicie darmowy) udostępnianym na warunkach licencji GNU General Public License w wersji 2.

Czytaj całość “Wprowadzenie do systemu kontroli wersji Git” »

Mała przygoda z Poecilotheria striata

Mała przygoda z Poecilotheria striata

Pare dni temu zdecydowałem się na hodowlę grupową kolejnego gatunku z rodzaju Poecilotheria – Poecilotheria striata [Pocock, 1895]. Mam już spore doświadczenie w hodowli tego rodzaju ptaszników, do tej pory wszystkie jednak hodowałem pojedyńczo.

Striata, jak wszystkie Poecilotherie ma bardzo silny jad, jest bardzo szybka, skoczna i impulsywna. Na wolności można je spotkać w lasach tropikalnych południowej części Indii, żywi się tym co większość ptaszników czyli np. wszelkiego rodzaju bezkręgowcami. Dorosłe samice tego gatunku mają ~7cm długości ciała, z rozprostowanymi odnóżami mierzą nawet do ~20cm.

Czytaj całość “Mała przygoda z Poecilotheria striata” »

Witajcie

Już wkrótce znajdziesz tutaj

Zdecydowałem się na uruchomienie strony wcześniej, tzn. przed tym jak znajdą się na niej artykuły/tutoriale, stwierdziłem że warto zaczekać aż Google ją znajdzie i zaindeksuje. Część artykułów jest już w przygotowaniu, niektóre z nich mają po kilka rozdziałów, pojawią się niebawem, prawdopodobnie w takiej kolejności:

Czytaj całość “Witajcie” »