欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標(biāo)題: Nucleo + Scratch,給你孩子的編程玩具 [打印本頁]

作者: 51hei大小    時(shí)間: 2016-6-17 16:47
標(biāo)題: Nucleo + Scratch,給你孩子的編程玩具
    不知道大家有沒有聽說的Scratch: https://scratch.mit.edu/    是由麻省理工開發(fā)的一個(gè)軟件,幫助孩子們從零開始學(xué)習(xí)編程。圖形化的程序設(shè)計(jì),萌萌噠的界面,想必能夠吸引住眾多孩子。不過這么好的軟件貌似在國內(nèi)知名度不高。

    后來,一個(gè)團(tuán)隊(duì)開發(fā)了一個(gè)名為S4A(Scartch for Arduino)的軟件:http://s4a.cat/   將Scartch與Arduino連接起來。結(jié)合了Scartch的編程優(yōu)點(diǎn),外加Arduino的眾多傳感器,一時(shí)間孩子們也能夠玩轉(zhuǎn)舵機(jī),開關(guān),以及模擬量的傳感器了。S4A使用了Arduino的6路AD采集接口,3路PWM接口和3路舵機(jī)接口,方便小孩子連接傳感器,實(shí)現(xiàn)自己的設(shè)計(jì)。

    后來,我覺得S4A這個(gè)玩意挺好玩的,看了一下桌子上的Nucleo,決定來移植一下。經(jīng)過大約3天的緊張工作,終于成功完成了移植。期間出了一個(gè)小小的問題耗費(fèi)了大約一天的時(shí)間。也就是Nucleo和S4A通訊的時(shí)候,S4A總是崩潰,一直未響應(yīng)。不知道是什么原因,期間一直在改動(dòng)自己的代碼。一天無果。第二天無意間換了FT232作為串口通訊的工具。竟然奇跡般的好了。事后發(fā)現(xiàn),只要是Nucleo的串口,不出幾分鐘,S4A必然崩潰。不知道是Nucleo串口的原因還是S4A的原因。

    在移植完之后,我簡(jiǎn)單的用S4A寫了一個(gè)呼吸燈的程序,突然發(fā)現(xiàn),用C很容易實(shí)現(xiàn)的東西,讓我來拖拽的時(shí)候竟然不知道如何去做了。。。
下面是程序截圖:


最后,給大家上傳一小段視頻看一下(由于社區(qū)限制,只能將視頻分成兩個(gè)壓縮包上傳),感興趣點(diǎn)個(gè)贊,不感興趣路過好了。


---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nucleo334的軟件包以上傳到社區(qū)。歡迎大家下載試用。
發(fā)帖的時(shí)候占用了3層樓。對(duì)這幾層的規(guī)劃:


---------------------------------------------------------------------------------------------------------------------------------------------------------------------
    軟件包已經(jīng)上傳,名為S4Nu.rar(Scartch for Nucleo)歡迎大家提前下載使用。另外需要特別注意的是:雖然Nucleo自帶了串口,但是在與S4A連接的時(shí)候不要使用這個(gè)串口。也不要使用USB連線將Nucleo與電腦相連。
    應(yīng)該對(duì)Nucleo使用外部供電。并使用USB轉(zhuǎn)串口工具,例如CP2102,F(xiàn)T232等連接電腦與Nucleo的串口。具體是什么原因暫時(shí)還未知。可能在接下來的幾天內(nèi)能夠解決這個(gè)問題,也可能解決不掉。下面就要說說如何設(shè)置Nucleo的硬件部分:




    因通訊的問題,給老外的技術(shù)支持發(fā)了一封郵件,幾天后,收到了一個(gè)回復(fù),大概意思說是他們的S4A只是為Arduino Uno和Duemienova定做的,并且在今后的升級(jí)中,會(huì)考慮兼容更多的板子。本以為這件事就這樣算了。

    沒想到,另一個(gè)人,猜測(cè)大概是S4A的開發(fā)人員,給回復(fù)了一封郵件。意思是他正在考慮讓S4A在LPC的ARM處理器上工作。讓我發(fā)送一下我的代碼,說不定他可以檢查到什么錯(cuò)誤。好消息,給你吧。

    在發(fā)送完STM32的代碼之后,靜等了幾天,昨晚收到了郵件回復(fù):也沒看出是什么軟件的問題,大概是USB轉(zhuǎn)串口的問題吧。



S4Nu.rar (2.49 MB, 下載次數(shù): 21)

視頻.rar (14.65 MB, 下載次數(shù): 13)



----------------------------偶是分隔線----------------------------------------------------


Scartch的簡(jiǎn)單編程

    如果你代碼下載完畢,串口連接完成,打開S4A之后,就可以看到6路AD模擬量和兩個(gè)開關(guān)的數(shù)字量的值了。圖中的COMx是你實(shí)際使用的串口。在我的電腦上,這個(gè)COM3是使用FT232轉(zhuǎn)換出來的。還要注意圖片中的旗幟的標(biāo)志和那個(gè)紅色的大圓點(diǎn)。旗幟代表運(yùn)行我們使用S4A拖拽的程序,圓點(diǎn)代表停止。


    在S4A的左上角可以看到動(dòng)作,控制,外觀,等等控件。里面有各種各樣的工具供我們使用。

    腳本這個(gè)位置就是我們寫程序的地方。只要將程序按照邏輯結(jié)構(gòu)放在這里就可以。一定要注意的是,開始的語句是一個(gè)“當(dāng)旗幟被點(diǎn)擊”的語句。這條語句類似于C語言中的main函數(shù),程序開始執(zhí)行的地方。下面就來簡(jiǎn)單的寫一個(gè)閃燈的程序。



    這就是我們平時(shí)在單片機(jī)中常寫的Hello world程序。是不是很簡(jiǎn)單呢?如果想修改延時(shí)的時(shí)間怎么辦?雙擊“等待1秒”中的1,然后填上你想要的時(shí)間并按回車。這個(gè)時(shí)間是小數(shù)的形式。可以是0.1 。

    我們平時(shí)在寫程序的時(shí)候,經(jīng)常會(huì)設(shè)置一個(gè)變量,用于存儲(chǔ)延時(shí)的時(shí)間。在S4A中,變量的設(shè)置也是支持的。在變量一欄中點(diǎn)擊“新建一個(gè)變量”,之后填上變量的名字,就出現(xiàn)很多關(guān)于這個(gè)變量操作的控件。比如設(shè)置變量的值,將變量增加一個(gè)數(shù)值等等。可是,為什么沒有減小變量的數(shù)值呢?其實(shí)只要將“將變量delayTime的值增加[]”中的空格處填寫一個(gè)負(fù)數(shù)就可以了。比如-10 。可是小孩子如果不知道負(fù)數(shù)怎么辦呢?


    在程序?qū)懲曛螅c(diǎn)擊右上角圓點(diǎn)旁邊的旗幟圖標(biāo)就可以運(yùn)行了。

   不知道你家孩子會(huì)不會(huì)喜歡上!


------------偶還是分隔線------------------------



S4A Arduino源代碼解析


準(zhǔn)備工具:



Arduino的函數(shù)
  1.     int main( void )
  2.     {
  3.             setup();
  4.             for (;;){
  5.                     loop();
  6.             }
  7.             return 0;
  8.     }
復(fù)制代碼

setup()和loop()是我們需要自己填充的。setup只會(huì)被調(diào)用一次,完成代碼的一些初始化工作。loop是需要一直循環(huán)執(zhí)行的。

Arduino控制IO引腳的幾個(gè)函數(shù)在arduino.h(SAM系列的在wiring_digital.h)中。

S4A的數(shù)據(jù)結(jié)構(gòu)
  1. typedef enum {
  2.   input, servomotor, pwm, digital }
  3. pinType;

  4. typedef struct pin {
  5.   pinType type;       //Type of pin
  6.   int state;         //State of an output
  7.   //byte value;       //Value of an input. Not used by now. TODO
  8. };  
復(fù)制代碼



上面的代碼在Arduino中確實(shí)能夠編譯。但是在C語言中確不能。不知道是不是C++中typedef的一個(gè)新特性,還是一個(gè)bug。我在移植的時(shí)候直接修改了這段:
  1. typedef struct pin {
  2.   pinType type;       //Type of pin
  3.   int state;         //State of an output
  4.   //byte value;       //Value of an input. Not used by now. TODO
  5. } pin ;
復(fù)制代碼

struct pin是一個(gè)結(jié)構(gòu)體,里面存儲(chǔ)了引腳的信息,包括引腳的type和引腳的state。type是引腳的模式,可以是input,servomotors,pwm或者digital。state是引腳的值,有效取值從0到1023 。
S4A規(guī)定:

S4A的Arduino源代碼中定義了一個(gè)14個(gè)元素的數(shù)組,用來表示D0~D13的引腳的信息和狀態(tài):
pin arduinoPins[14]; //Array of struct holding 0-13 pins information
S4A對(duì)每一個(gè)引腳的功能都加以區(qū)分:
[原文]
Components have to be connected in a particular way. S4A allows for 6 analog inputs (analog pins), 2 digital inputs (digital pins 2 and 3), 3 analog outputs (digital pins 5, 6 and 9), 3 digital outputs (pins 10, 11 and 13) and 4 special outputs to connect Parallax continuous rotation servomotors (digital pins 4, 7, 8 and 12).



S4A的通信協(xié)議
根據(jù)S4A的通信協(xié)議(在附件中),每隔一段時(shí)間(20ms,在下文中會(huì)說明為什么是20ms),Arduino(或者Nucleo)應(yīng)該依次將A0~A5的模擬量,D2,D3的電平值依次上傳。共8組(一組數(shù)據(jù)由兩個(gè)字節(jié)組成)數(shù)據(jù)。每一組數(shù)據(jù)都有相應(yīng)的格式:
7 6 5 4 32
1 0
Byte1 1 N N N N R R R
Byte2 0 R R R R R R R

舉個(gè)例子:比如某一上傳時(shí)刻,采集到了A0~A5的電壓制為1023,D2為高電平,D3位低電平,那么應(yīng)該上傳:
B1_0000_111 B0_1111111 //A0,1023
B1_0001_111 B0_1111111 //A1,1023
B1_0010_111 B0_1111111 //A2,1023
B1_0011_111 B0_1111111 //A3,1023
B1_0100_111 B0_1111111 //A4,1023
B1_0101_111 B0_1111111 //A5,1023
B1_0110_111 B0_1111111 //D2,HIGH
B1_0111_000 B0_0000000 //D3,LOW

Arduino采集AD接口的信息的時(shí)候,一個(gè)AD接口采集了5次,取五次結(jié)果的中間值作為最后上傳的結(jié)果:
  1.     for (byte p = 0; p < 5; p++)
  2.             readings[p] = analogRead(sensorIndex);
  3.         insertionSort(readings, 5); //sort readings
  4.         sensorValues[sensorIndex] = readings[2]; //select median reading
復(fù)制代碼

insertionSort是插入排序,將5次結(jié)果排序,那么五次結(jié)果中的第二個(gè)一定是中間值。
索引
0 12
34
原始數(shù)據(jù)
1023 1018 1020 1019 1021

索引
0 1 2 3 4
排序之后
1018 1019 1020 1021 1023


在源代碼中,將數(shù)據(jù)打包上傳的代碼:(Serial.write發(fā)送8位無符號(hào)整數(shù))
  1.     void ScratchBoardSensorReport(byte sensor, int value) //PicoBoard protocol, 2 bytes per sensor
  2.     {
  3.       Serial.write( B10000000
  4.         | ((sensor & B1111)<<3)
  5.         | ((value>>7) & B111));
  6.       Serial.write( value & B1111111);
  7.     }
復(fù)制代碼

而每隔大約75ms,S4A會(huì)將D4~D13的值傳給Arduino。因?yàn)檫@個(gè)時(shí)間很短,為了保證數(shù)據(jù)的接受完整,在實(shí)際移植的時(shí)候,應(yīng)該建立RingBuffer緩沖區(qū),采用中斷接收的方式。

[原文]Protocol                        
S4A interacts with Arduino by sending the actuator states and receiving sensor states every 75 ms, therefore the pulse width needs to be greater than this time period. The data exchange follows the PicoBoard protocol and needs a specific program (firmware) to be installed in the board. Please refer to the Downloads section for further instructions on how to do so.

當(dāng)Arduino接收到S4A傳來的數(shù)據(jù)之后,會(huì)對(duì)數(shù)據(jù)解碼,獲取N編號(hào)和R的值:
  1.     pin = ((actuatorHighByte >> 3) & 0x0F);
  2.     newVal = ((actuatorHighByte & 0x07) << 7) | (actuatorLowByte & 0x7F);
復(fù)制代碼
如果R值需要更新:
  1.     if(arduinoPins[pin].state != newVal)
  2.     {
  3.         arduinoPins[pin].state = newVal;
  4.         updateActuator(pin);
  5.     }
復(fù)制代碼
而查閱updateActuator的代碼,發(fā)現(xiàn)并沒有更新舵機(jī)的代碼(具體什么原因,會(huì)和上文提到的20ms一起解釋)。
  1.     void updateActuator(byte pinNumber)
  2.     {
  3.       if (arduinoPins[pinNumber].type==digital) digitalWrite(pinNumber, arduinoPins[pinNumber].state);
  4.       else if (arduinoPins[pinNumber].type==pwm) analogWrite(pinNumber, arduinoPins[pinNumber].state);
  5.     }
復(fù)制代碼
20ms?
loop函數(shù)是整個(gè)調(diào)用過程:
  1.     void loop()
  2.     {
  3.       static unsigned long timerCheckUpdate = millis();

  4.       if (millis()-timerCheckUpdate>=20)
  5.       {
  6.         sendUpdateServomotors();
  7.         sendSensorValues();
  8.         timerCheckUpdate=millis();
  9.       }

  10.       readSerialPort();
  11.     }
復(fù)制代碼

由于C和C++的原因,上述代碼在C中并不能成功編譯。因此我修改為:
  1.     void loop()
  2.     {
  3.       static unsigned long timerCheckUpdate = 0;
  4.       //...
  5.     }
復(fù)制代碼

   millis()是Arduino中用于獲取自CPU啟動(dòng)以來經(jīng)歷的ms數(shù)。將timerCheckUpdate改為0,只不過第一次執(zhí)行的時(shí)候if中的語句也能夠執(zhí)行罷了。在這20ms中,更新了舵機(jī)的數(shù)值,上傳了A0~A5,D2,D3的狀態(tài)。在最后更新了timerCheckUpdate時(shí)間戳,保證下一次執(zhí)行是在20ms之后。如果這時(shí)候串口的接受緩沖區(qū)中存在數(shù)據(jù),讀出來,并解析。
    先科普一下舵機(jī)的知識(shí):舵機(jī)的轉(zhuǎn)動(dòng)角度是0~180度,轉(zhuǎn)動(dòng)角度的大小是由pwm的占空比決定的。pwm的周期必須為20ms。pwm波形中高電平的時(shí)間大約在500us~2500us之間。500us代表0度,2500us代表180度。
  1.     void sendUpdateServomotors()
  2.     {
  3.       for (byte p = 0; p < 10; p++)
  4.         if (arduinoPins[p].type == servomotor) servo(p, arduinoPins[p].state);
  5.     }

  6.     void servo (byte pinNumber, byte angle)
  7.     {
  8.       if (angle != 255)
  9.         pulse(pinNumber, (angle * 10) + 600);
  10.     }

  11.     void pulse (byte pinNumber, unsigned int pulseWidth)
  12.     {
  13.       digitalWrite(pinNumber, HIGH);
  14.       delayMicroseconds(pulseWidth);
  15.       digitalWrite(pinNumber, LOW);
  16.     }
復(fù)制代碼
servo這個(gè)函數(shù)將S4A發(fā)送來的舵機(jī)的轉(zhuǎn)動(dòng)角度(0~180)轉(zhuǎn)換成為實(shí)際的高電平時(shí)間。然后通過延時(shí)來產(chǎn)生一定時(shí)間的高電平。為了保證舵機(jī)能夠正常運(yùn)轉(zhuǎn)。在移植的時(shí)候必須提供一個(gè)精度較高的delayMicroseconds函數(shù)。

S4A的Arduino函數(shù)解析就這么多,希望大家都能夠移植到自己的單片機(jī)中。
Have Fun!

S4AFirmware16.rar (2.61 KB, 下載次數(shù): 16)

s4a-protocol.pdf (74.33 KB, 下載次數(shù): 19)






歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1