środa, 27 kwietnia 2016

Restartowanie kart sieciowych w Powershell'u

Czasem karty wifi potrafią być włączone, ale przestają się łączyć do widocznych sieci. Często dzieje się tak przy używaniu hibernacji w laptopach. Być może wina leży w źle napisanych sterownikach lub innych własnościach sprzętu. Można łatwo sobie z tym poradzić stosując prosty skrypt w Powershell'u:

Skrypt działa najlepiej, gdy będzie odpalony z prawami administratora.

środa, 20 kwietnia 2016

Podstawowe błędy w programowaniu (początkujących)

1. Indeksowanie

Zasadnicze pytanie: indeksujemy od 0 czy 1? Pierwszy element ma indeks 0 czy 1? Problem który dotyka niektórych początkujących uczących się nowego języka, szczególnie gdy pierwszym z nich był taki, który obsługiwał indeksowanie tablic bardziej "matematycznie", formalnie czyli pierwszy element w tablicy miał indeks 1. Może to prowadzić do szeregu błędów w stylu "off by one".

int n = 10;
int[] tabs = new int[n];
for (int i=1; i<=n; i++)
{
 tabs[i] = i+1;
}

W powyższym przypadku popełniono dwa błędy: pierwszy polega na pominięciu pierwszego elementu (o indeksie zero i rozpoczęciu indeksowania od 1). Drugi błąd to wyjście poza granice tablicy (IndexOutOfRangeException) przez źle skonstruowany warunek wykonania pętli.

2. Wyrażenia warunkowe

Początkujący programiści dosyć często zachłystują się możliwościami jakie daje instrukcja if. Są w stanie "zaprogramować" rozmaite działania programu bazując jedynie na tej instrukcji (oraz instrukcji switch..case gdy ją poznają) poprzez budowanie rozległych łańcuchów if..else..if..else.

int e = 2;
//...
if (e==0)
{
 Console.Write("Brak danych");
}
else if (e==1)
{
 Console.Write("Błędne dane");
}
else if (e==2)
{
 Console.Write("Inny problem");
}

W takim przypadku warto rozważyć inne podejście i zaprogramować bardziej czytelne, i skuteczne rozwiązanie.

int e = 2;
//...
string[] errors = new string[] { "Brak danych", "Błędne dane", "Inny problem" };
Console.WriteLine(errors[e]);

3. Wyrażenia logiczne

Logika boolowska to podstawa w formułowaniu działania programu. Opierają się na niej wspomniane wcześniej wyrażenia warunkowe. Budowanie takich wyrażeń musi być zawsze przemyślane, gdyż nieodpowienio zbudowane wyrażenia mogą być przyczyną błędów, a nawet mieć wpływ na wydajność.

W przypadku zastosowania operatorów logicznych && i || ważna jest kolejność operandów. W przypadku sumy logicznej, gdy pierwszy z nich jest false to zaniechane jest dalsze przetwarzanie wyrażenia. W przypadku alternatywy, takie zaniechanie następuje gdy pierwszy z operandów jest true.

Skrócone przetwarzanie wyrażeń logicznych zyskuje na znaczeniu gdy, przewidujemy która część wyrażenia będzie powodowała skrócenie przetwarzania wyrażenia.

4. Operatory as i is oraz rzutowanie

Rzutowanie typów w C# można przeprowadzić na dwa sposoby. Podając nazwę typu w nawiasie przed odwołaniem do obiektu (Control)zmienna; lub przy pomocy operatora as zmienna as Control.

W pierwszym przypadku gdy rzutowanie nie jest możliwe, zostanie wyrzucony wyjątek, w drugim przypadku otrzymamy null. Rzutowanie przez operator as można stosować tylko dla typów referencyjnych i zerowalnych (Nullable<>).

W większości przypadków, wyjątków związanych z nieprawidłowym rzutowaniem typów można uniknąć przez stosowanie operatora is. Operator ten zwraca true jeżeli sprawdzana zmienna jest typem podanym z prawej strony operatora, false w przeciwnym wypadku.

if (zmienna is Control)
{
   zmienna2 = (Control)zmienna;
}

5. Konkatenacja string'ów

Nieznajomość klas i metod z frameworka może być przyczyną powstawania problemów wydajnościowych. W tym przypadku nieodpowiednie

string[] animals = { "kot", "pies", "mysz" };

string allAnimals = string.Empty;

foreach (string s in animals)
{
    allAnimals += s + ", ";
}

Console.Write(allAnimals);

Powyższy kod jest bardzo nieefektywny pod kątem wykorzystania pamięci. Łącząc elementy z tabeli animals w pętli foreach, na każdą iterację przypadają aż trzy alokacje pamięci dla nowych ciągów znakowych. String jest typem, którego rozmiar jest ustalany w momencie przypisania. W momencie przypisywania nowego ciągu znaków do zmiennej tego typu, następuje powstanie nowego obiektu klasy string. Przy dużej ilości iteracji kod taki staje się problematyczny, bo zaczyna mocno obciążać zasoby przez ciągłe alokacje pamięci, oraz zmusza Garbage Collector do częstszego porządkowania pamięci - co ma wpływ na wydajność.

Kod poniżej działa prawie tak samo, ale znacznie efektywniej. Wykorzystuje wbudowaną metodę Join(), która jest zoptymalizowana do wykonania tego zadania. Wewnętrznie sama alokuje odpowiednią ilość pamięci dla łączonych ciągów.

string[] animals = { "kot", "pies", "mysz" };

string allAnimals = string.Join(", ", animals);

Console.Write(allAnimals);

wtorek, 8 marca 2016

Digispark Attiny85 - szybki start

Czym jest Digispark? To miniaturowa płytka z mikrokontrolerem Attiny85 oparta o ideę Arduino. Czyli korzystamy z IDE Arduino i niektórych bibliotek. Dlaczego niektórych? A dlatego, że nie wszystko się zmieści łącznie z programem w pamięci mikrokontrolera Attiny85 - 8kB, która to pamięć jest jeszcze zmniejszona o 2kB przez bootloader. Więc dużo nie zostaje. Dokładna specyfikacja. Układ można zasilać wprost z portu USB, lub przez odpowiednie piny na płytce. Przez to, że mikrokontroler jest wpięty wprost do portu USB, należy uważać by nie uszkodzić portu w komputerze przez zwarcie w budowanym na bazie płytki układzie. Producent poleca podpinać płytkę przez hub USB, lub uruchamiać korzystając z zewnętrznego zasilacza.

Jak zacząć

1. Sterowniki

Pobieramy sterowniki - można pobrać plik _DriverFiles.7z lub pobrać całe repozytorium.
Może się zdarzyć, że system po zainstalowaniu nie widzi płytki (pojawia się nieznane urządzenie). Wtedy należy ręcznie wskazać sterowniki do płytki w menedżerze urządzeń:
  1. Klikamy prawym klawiszem myszy na "Nieznane urządzenie";
  2. W zakładce "Sterownik" wybieramy "aktualizuj sterownik";
  3. Potem "Przeglądaj mój komputer w poszukiwaniu oprogramowania sterownika";
  4. Następnie "Pozwól mi wybrać z listy sterowników urządzeń na moim komputerze";
  5. Na następnym ekranie wybieramy pozycję "Pokaż wszystkie urządzenia" i dajemy dalej;
  6. W kolejnym oknie klikamy przycisk "Z dysku" i w oknie dialogowym wyboru plików wybieramy plik inf w katalogu ze sterownikami do Digisparka;
  7. Akceptujemy to że sterownik nie jest podpisany cyfrowo;
  8. Po zainstalowaniu sterownika, odłączamy na chwilę płytkę od portu i po ponownym włączeniu powinna być już widoczna jako "Digispark USB".
W moim przypadku urządzenie stało się wykrywalne po bezpośrednim wpięciu do portu USB komputera, wpięcie przez hub powoduje, że płytka nie jest wykrywana.

2. IDE Arduino

W Arduino IDE dodajemy nowe źródło konfiguracji płytek http://digistump.com/package_digistump_index.json:

Później w "Menedżerze płytek" instalujemy "Digistump AVR Boards"

3. Wgrywamy pierwszy program

W porównaniu do klasycznego Arduino, program wgrywa się w momencie wpięcia płytki do portu USB. Bootloader przez około 5 sekund oczekuje na zaprogramowanie. Dlatego najpierw w Arduino uruchamia się załadowanie szkicu, a dopiero pod koniec po komunikacie, mówiąc o wpięciu płytki wpina się ją (zazwyczaj jest na to przeznaczone 60 sekund) i następuje rzeczywiste załadowanie programu.
Na początek trzeba wybrać odpowiednią płytkę:

Później kompilujemy i ładujemy szkic do płytki (płytka musi być odłączona) i czekamy na komunikat:
W tym momencie podłączamy płytkę i po jej wykryciu nastąpi załadowanie szkicu:
Gotowe! Pierwszy szkic załadowany.

Podsumowanie

Płytka jest niewielka, szkice które można załadować też muszą być niewielkie. W porównaniu do Arduino, oferuje znacznie mniejsze możliwości. Plusem płytki są małe wymiary. Minusem jednak problematyczne działanie z USB. Samo ładowanie szkiców nie jest aż takim dużym problemem, można się przyzwyczaić, że najpierw szkic trzeba skompilować a potem podłączyć płytkę aby się załadował. Większym problemem jest wykrywanie urządzenia USB, sterowniki oraz huby USB, które nie zawsze chcą współpracować.

Mimo tego płytka Digispark może być ciekawą podstawą do projektów. Dołączone liczne przykłady pokazują różne zastosowania płytki. Mimo niewielkiej ilości pinów, można sobie poradzić budując projekty oparte o magistralę I2C.

Moim skromnym zdaniem to coś więcej niż tylko ciekawostka.