2019年8月19日 星期一

對於小孩子的程式教學Code.org,Blockly Games,Kodu Game Lab,E-game

         自從接觸arduino之後,利用原本就有的3D印表機,可以自己做出一些小玩意,對於非資訊、工程出身的我來說,就覺得寫程式是件有趣但又很難入門的挑戰,很多本科系理所當然的東西,對我是不知所云,總之就是覺得很難,更不要說要教小孩了,不過在注意到日本要將程式放入小學課程的新聞,電視節目跟網路也常常播放美國有針對小孩的教學,我就想台灣的教育部官僚一定也會不知為何的加進學校課程,在問過自己小孩之後,確實發現學校有在教,想到那些不知人間疾苦的官員一定會自以為是的做一些不知所云的課綱,為了要讓自己的小孩能接觸真實的狀況,就自己試著來了解看看。

         底下是我玩過之後,認為要跟小孩子解釋時,可以進行的順序跟注意的重點,就我自己半路學程式的經驗,即使上完這些課程,如果沒有可以學以致用的成果,還是不知道學了什麼,依照目前學校的教法,是讓小孩子知道有這些程式工具,但是這些工具能幫助他做什麼,就著墨不多,其實這本來就是意料中事,因為小孩程度不同,而認真的老師課程多又很忙,所以如果由家長跟著一起學習,能夠做一些啟發,我相信效果會比較好。

         雖然這些網站是各自獨立的,基本上可以各自完成,但有些部分我覺得是可以交叉進行,比如在Code.org熟悉積木之後,然後在Blockly Games學積木的屬性(參數),再回頭看Code.org的內容,對於運用積木的方式也許會更有概念


Code.org(https://studio.code.org/courses)
        台灣小學有使用這個網站,這是在教怎麼運用積木的方式寫程式,先認識積木、熟悉積木,再使用積木來寫程式。他的課程雖然是有寫針對哪些年齡層,但其實就是對於完全不懂積木是什麼的人,是一個入門的好地方,所以一個新手能夠從頭開始,至於"不插電的教學"是要激起小孩子的興趣的手作遊戲,青少年以上可以參考就好。

        還有,如果不想花那麼長的時間,可以試試"一小時玩程式"的課程,這個就有點像速成班,省略為了加深印象而不斷重複的課程,一個課程就是一個觀念,大人可以直接做這個。
另外,在使用積木的時候,還可以看程式碼,因為我不知道今後寫程式的發展是不是都用積木,所以讓小孩子對程式碼有概念也是必要的,還有,也要讓小孩子理解程式碼都是英文這件事,這樣才不會在往後,萬一討厭英文也會影響到寫程式。

         其實我覺得在這個地方學習就夠了,但是如果想加深概念的話,可以試試其他兩個,因為重點不一樣。

Blockly Games(https://blockly-games.appspot.com/)
        老實說,這個網站不是針對小孩子,我覺得有難度,台灣的高中課程是用這個,對於小學生只要完成前面兩個課程,讓小孩子對於積木的特徵、屬性(參數)有概念就好,如果想加強條件式的概念,可以繼續做下去,對於接下來的KODU是有幫助的



Kodu Game Lab(https://www.kodugamelab.com/ 
        台灣小學也有用這個,這就不是網站,而是需要安裝的應用程式,因為這個程式提供的物件很多,其實就是一個可以開發遊戲的軟體,對於一個很有想法的小孩子而言,這是一個很好發揮的工具。
        在完成了教學課程之後,發現這是一個很強調[當]發生什麼的時候,[做]什麼,的教學軟體,因為整個介面就像是個遊戲,對於小孩子來說,應該是可以很快進入,而不太有排斥感,可惜的是,在介紹物件的屬性選擇時,順序上有點問題,造成有些需要先知道的知識,在下一個課程才會出現,不過我自己先玩過,在教小孩的時候,就可以適時的說明。
        因為世界可以做得很大,可以放的物件數量就可以很多,地形也可以做很多變化,這樣的好處,是可以放任小孩子自己發展,但也變成一個盲點,如果一個小孩子沒有任何想法,把他放到這樣的世界裡,他就只會到處放物件,到處改地形,卻不知道要設計什麼,就好像把人放到一個開放的世界,不同個性的人會有不同的行為,但是大部分的人卻不知所措,原本的好處就變成了困擾。

        這時候引導的老師就很重要,因為可以讓小孩子的想像力在這裡延伸,變成一個互動的世界,但是積木的內容就必須要很有邏輯,這會關係到互動的結果,能夠把互動做好的話,這會是一個很好的開放世界的開始。

E-game
        雖然學校有在教這個,但我卻沒辦法進行下去,因為前幾個教學網站所設計的關卡都會適可而止,在玩到快要很煩之前就會結束,但是這個網站會讓我玩到很重複很煩,所以就沒什麼評論。

mBlock + Arduino + Appinventor
          在學過程式之後,就要實際體驗一下程式的效果,最好的方法就是跟日常生活有關的物品,因為arduino的價錢不高,大概五百元以內就可以買到本體跟幾個sensor還有一些線,只要善用sensor就有很多變化,再加上可以用藍芽模組跟手機連線,手做個藍牙夜燈就會很有成就感,我覺得這個回報率還滿高的,其實台灣都把對岸的價錢加倍賣,能淘就自己淘。
          我自己用這些東西加上網路的資源做了幾個東西,尤其是Otto讓我很驚豔,我一直相信往後的社會可能用AI+機器人,先取代勞力工作,再取代思考工作,可以先用Otto做初步的說明。


LEGO MindStorms EV3
      對我來說,相比之下就是個奢侈品, 一組一萬,雖然說運用積木創作力無限,但就以我認識的人來說,拚完幾個型態,甚至還去上萬的課程之後,小孩子就不太碰了,單純就是組完之後看它動起來的時候,那個爽度吧。
        當然,對於那些很有想法,又很會拼樂高的小孩子而言,這就是個很有發展力的產品,因為這是一個真正可以動的物品,它可以把你的想像表現出來,而不是只在電腦、頭腦裡面。
      
Roblox

2019年7月1日 星期一

如何自製arduino的函式庫

動機是來自Otto。

因為自己組合了有手的Otto,但是APP卻都是只有腳的部分,所以想說自己編寫APP看看,發現自己要重複編寫那些動作很麻煩,而library的函式庫就是在處理這種重複功能用的,就想來研究看看。

在看過幾本書幾篇文章之後,嗯,完全看不懂,果然代誌不是憨人想得那麼簡單,於是又來記錄自己的學習過程。

我是先參考底下這一篇。

https://chtseng.wordpress.com/2017/05/31/%E5%A6%82%E4%BD%95%E7%B7%A8%E5%AF%ABarduino-library/

釐清自己對於library的觀念就是會不斷使用的程式碼寫成函式,就可以只呼叫函式名稱來使用,不用再重複整段程式碼。

所以,首先就是確認自己要改成library的程式碼可以用,再以既定的格式改編。

依照格式來說要準備三個檔案,
函式名稱.h                   (這是定義函式功能的變數、參數,稱為header file)
函式名稱.cpp               (這是C++編譯使用的檔案,執行的動作放這邊,稱為source file)
keywords.txt                 (這是在編寫程式有寫到關鍵字時,要變色,檔案可有可無)

這時候發現一開始看不懂的問題就是,不知道該把什麼放到哪裡,因為作者都很熟了,所以文章的內容就很順理成章的把程式碼都已經分類到兩個檔案去了,但是我卻完全搞不清楚為什麼要這樣分類。

就走一步算一步了。

在上面連結有一個例子,說明如何將閃爍的功能寫成library。
這時候已經稍有概念了,但是還似懂非懂,看了幾篇還是有疑問,最後想說找arduino官網的說明看看,底下是說明摩斯密碼的例子,看起來比較基礎的樣子,我先紀錄這個功能試試看之後,再回頭看其他的。

https://www.arduino.cc/en/Hacking/LibraryTutorial

摩斯密碼適用亮光的時間長跟短來組合出文字,底下就是長跟短的程式碼

void dot()
{
  digitalWrite(pin, HIGH);
  delay(250);
  digitalWrite(pin, LOW);
  delay(250);
}

void dash()
{
  digitalWrite(pin, HIGH);
  delay(1000);
  digitalWrite(pin, LOW);
  delay(250);
}

再根據要幾個長跟幾個短來呼叫就可以

void loop()
{
  dot(); dot(); dot();
  dash(); dash(); dash();
  dot(); dot(); dot();
  delay(3000);
}

完整的程式碼

int pin = 13;

void setup()
{
  pinMode(pin, OUTPUT);
}

void loop()
{
  dot(); dot(); dot();
  dash(); dash(); dash();
  dot(); dot(); dot();
  delay(3000);
}

void dot()
{
  digitalWrite(pin, HIGH);
  delay(250);
  digitalWrite(pin, LOW);
  delay(250);
}

void dash()
{
  digitalWrite(pin, HIGH);
  delay(1000);
  digitalWrite(pin, LOW);
  delay(250);
}

確認這段程式碼的動作沒有問題,接下來就是開始拆解。
以功能來說,就是長dash跟短dot,還有一個變數,就是腳位。

我們先在header file定義功能跟變數,使用的是class,private是呼叫Morse時才能使用, public則是整段程式碼都可以用,基本上,盡量使用private,減少公用記憶體的用量

class Morse
{
  public:
    Morse(int pin);
    void dot();
    void dash();
  private:
    int _pin;
};

不過,我們自己定義的功能根本上來說,是使用arduino的基本功能,所以我們需要把arduino的功能放進去。

#include "Arduino.h"

最後是檔案頭尾要放上宣告header file用的字眼。

#ifndef Morse_h
#define Morse_h

// the #include statment and code go here...

#endif


所以完整的header file會是
#ifndef Morse_h
#define Morse_h

#include "Arduino.h"

class Morse
{
  public:
    Morse(int pin);
    void dot();
    void dash();
  private:
    int _pin;
};

#endif

接著是source file,先把變數的作用寫出來,就是指定腳位並設定為output。

Morse::Morse(int pin)
{
  pinMode(pin, OUTPUT);
  _pin = pin;
}

接著是長跟短的時間
void Morse::dot()
{
  digitalWrite(_pin, HIGH);
  delay(250);
  digitalWrite(_pin, LOW);
  delay(250);  
}

void Morse::dash()
{
  digitalWrite(_pin, HIGH);
  delay(1000);
  digitalWrite(_pin, LOW);
  delay(250);
}

有一個雙冒號的記號::,那是指附屬功能,比如void Morse::dot()就是指附屬在Morse的dot功能,用這個就可以描述變數跟功能。

其實,我還有一個地方不懂,既然腳位已經用pin變數來指定了,為什麼還要再加一個_pin,而且還設定_pin=pin,用兩個變數來代表同一個意思。

雖然source file不需要頭尾宣告,但是,還是要把需要的功能寫進來,

#include "Arduino.h"
#include "Morse.h"

因此,完整的source file的內容就會是

#include "Arduino.h"
#include "Morse.h"

Morse::Morse(int pin)
{
  pinMode(pin, OUTPUT);
  _pin = pin;
}

void Morse::dot()
{
  digitalWrite(_pin, HIGH);
  delay(250);
  digitalWrite(_pin, LOW);
  delay(250);  
}

void Morse::dash()
{
  digitalWrite(_pin, HIGH);
  delay(1000);
  digitalWrite(_pin, LOW);
  delay(250);
}

有了完整的header file 跟source file,就可以引用來寫程式了。
#include <Morse.h>

Morse morse(13);

void setup()
{
}

void loop()
{
  morse.dot(); morse.dot(); morse.dot();
  morse.dash(); morse.dash(); morse.dash();
  morse.dot(); morse.dot(); morse.dot();
  delay(3000);
}


看來要會拆解程式,才能夠學好library,上面的例子是給了一個變數,腳位用的,
我找到一個例子,是給三個變數的,如果可以看得懂,應該可以說入門了吧。
http://yehnan.blogspot.com/2013/01/arduino.html