久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9892|回復: 0
打印 上一主題 下一主題
收起左側

Nucleo + Scratch,給你孩子的編程玩具

[復制鏈接]
跳轉到指定樓層
樓主
    不知道大家有沒有聽說的Scratch: https://scratch.mit.edu/    是由麻省理工開發的一個軟件,幫助孩子們從零開始學習編程。圖形化的程序設計,萌萌噠的界面,想必能夠吸引住眾多孩子。不過這么好的軟件貌似在國內知名度不高。

    后來,一個團隊開發了一個名為S4A(Scartch for Arduino)的軟件:http://s4a.cat/   將Scartch與Arduino連接起來。結合了Scartch的編程優點,外加Arduino的眾多傳感器,一時間孩子們也能夠玩轉舵機,開關,以及模擬量的傳感器了。S4A使用了Arduino的6路AD采集接口,3路PWM接口和3路舵機接口,方便小孩子連接傳感器,實現自己的設計。

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

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


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


---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nucleo334的軟件包以上傳到社區。歡迎大家下載試用。
發帖的時候占用了3層樓。對這幾層的規劃:
  • 簡單的介紹一下S4A軟件如何使用。帶領大家拖拽一個小程序。
  • 全面介紹一下如何將S4A在Arduino上的軟件移植到STM的Nucleo板上。
  • 暫時還沒想好能干點什么。


---------------------------------------------------------------------------------------------------------------------------------------------------------------------
    軟件包已經上傳,名為S4Nu.rar(Scartch for Nucleo)歡迎大家提前下載使用。另外需要特別注意的是:雖然Nucleo自帶了串口,但是在與S4A連接的時候不要使用這個串口。也不要使用USB連線將Nucleo與電腦相連。
    應該對Nucleo使用外部供電。并使用USB轉串口工具,例如CP2102,FT232等連接電腦與Nucleo的串口。具體是什么原因暫時還未知。可能在接下來的幾天內能夠解決這個問題,也可能解決不掉。下面就要說說如何設置Nucleo的硬件部分:
  • 將Nucleo復位按鍵(板子上面的那個黑色開關)下面的短路帽由U5V改成E5V。這樣能切換到外部電源供電。
  • 將Nucleo背面的焊橋SB62和SB63短接。這樣可以使PA2和PA3引腳連到Arduino接口的D0(Rx)和D1(Tx)。如果你懶得焊接,也可以使用CN3排針(STLINK)部分。CN3標記的RX接的是Nucleo的TX,而CN3的TX接的是Nucleo的RX。
  • 使用外部電源給Nucleo供電。外部電源5V接到Morpho左邊排針的E5V,將外部電源GND接到Nucleo的GND。
  • 將你使用的串口工具的TX接D0或者CN3的TX串口工具的RX接D1或者CN3的RX串口工具的GND接Nucleo的GND,并將串口工具連接到電腦。
  • 打開S4A軟件,S4A會自動搜索電腦上的串口,判斷包格式。如果包正確,那么可以順利連接。
  • 順利連接之后可以看到S4A軟件上顯示的6路AD量和兩路數字量輸入。



  • 2015.6.9   更新2樓,介紹S4A如何使用。
  • 2015.6.10 更新3樓,介紹S4A Arduino源代碼。



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

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

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



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

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



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


Scartch的簡單編程

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


    在S4A的左上角可以看到動作,控制,外觀,等等控件。里面有各種各樣的工具供我們使用。
  • 動作一欄含有數字引腳的輸出,舵機控制,pwm輸出等。是對硬件的實際控制。
  • 控制一欄中是常見的循環,if else分支語句,延時等函數。
  • 數字和邏輯運算里面含有常用的大于小于判斷,加減乘除等語法。
  • 變量一欄中可以設置一個自己的變量,用于存儲AD的采集值,pwm的輸出值等等。更奇葩的是,還有鏈表這個東西。一直搞不清楚對小孩子而言,鏈表可以干什么。

    腳本這個位置就是我們寫程序的地方。只要將程序按照邏輯結構放在這里就可以。一定要注意的是,開始的語句是一個“當旗幟被點擊”的語句。這條語句類似于C語言中的main函數,程序開始執行的地方。下面就來簡單的寫一個閃燈的程序。



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

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


    在程序寫完之后,點擊右上角圓點旁邊的旗幟圖標就可以運行了。

   不知道你家孩子會不會喜歡上!


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



S4A Arduino源代碼解析


準備工具:
  • Arduino IDE(如果沒有,可以使用文本編輯工具代替。比如Notepad++或者記事本)。
  • S4A串口通訊協議。在附件中提供下載。
  • S4A Arduino通訊源代碼。在附件中提供下載。



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

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

Arduino控制IO引腳的幾個函數在arduino.h(SAM系列的在wiring_digital.h)中。
  • pinMode用于設置引腳的工作方式,可以是INPUT,OUTPUT。
  • digitalWrite是設置引腳的電平值。類似于STM32庫文件中的GPIO_WriteBit。
  • digitalRead是讀取引腳的電平值。類似于STM32庫文件中的GPIO_ReadInputDataBit。
  • analogRead讀取模擬引腳的電壓值。因為Arduino是10位AD,所以這個函數的返回值在0-1023之間。
  • analogWrite并不是一個DA輸出,而是pwm輸出。在Arduino SAM中被改為了pwmWrite。
    1.     void pinMode(uint8_t, uint8_t);
    2.     void digitalWrite(uint8_t, uint8_t);
    3.     int digitalRead(uint8_t);
    4.     int analogRead(uint8_t);
    5.     void analogWrite(uint8_t, int);
    復制代碼


S4A的數據結構
  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. };  
復制代碼



上面的代碼在Arduino中確實能夠編譯。但是在C語言中確不能。不知道是不是C++中typedef的一個新特性,還是一個bug。我在移植的時候直接修改了這段:
  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 ;
復制代碼

struct pin是一個結構體,里面存儲了引腳的信息,包括引腳的type和引腳的state。type是引腳的模式,可以是input,servomotors,pwm或者digital。state是引腳的值,有效取值從0到1023 。
S4A規定:
  • 如果一個引腳是input(用于輸入)或者digital(用于輸出),那么state取值只能0或者1023 。0表示低電平,1023表示高電平。
  • 如果一個引腳是servomotor(舵機接口)或者pwm,state的取值只能從0到255 。表示占空比。0表示占空比為0%,255表示占空比為100% 。

S4A的Arduino源代碼中定義了一個14個元素的數組,用來表示D0~D13的引腳的信息和狀態:
pin arduinoPins[14]; //Array of struct holding 0-13 pins information
S4A對每一個引腳的功能都加以區分:
[原文]
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).
  • A0-A5,6路模擬量輸入。引腳信息沒有存放在arduinoPins數組中。
  • D0,D1是通訊串口的RX和TX。保留給串口使用。
  • D2,D3是兩路數字開關量。可以用來接按鍵。pinType為input。
  • D4,D7,D8是舵機接口。pinType為servomotors。這三個舵機接口是通過延時函數來實現的。即使Nucleo板上發現這3個接口不是pwm接口也無所謂。
  • D5,D6,D9是pwm接口。pinType為pwm。使用邏輯分析儀測試,這三個pwm接口的周期都為2ms,頻率為500Hz。
  • D10,D11,D12,D13是數字輸出接口。pinType為digital。可以驅動led燈等設備。



S4A的通信協議
根據S4A的通信協議(在附件中),每隔一段時間(20ms,在下文中會說明為什么是20ms),Arduino(或者Nucleo)應該依次將A0~A5的模擬量,D2,D3的電平值依次上傳。共8組(一組數據由兩個字節組成)數據。每一組數據都有相應的格式:
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
  • 每一個字節的最高位是一個標志位。Byte1的最高位必須為1,Byte2的最高位必須是0.這樣就可以判斷包是否正確。因為Byte1一定是大于127的,Byte2一定是小于127的。
  • N表示數據編號。Arduino上傳至S4A:A0~A5模擬量的編號是0~5,D2編號是6,D3編號為7.
  • N表示數據編號。S4A下傳至Arduino:D4~D13的編號為4~13 。
  • R表示需要上傳的數據。由10位組成,可以表示0-1023的最大值。這也就是為什么STM32可以達到12位AD采集,卻要設置成10位的原因了。

舉個例子:比如某一上傳時刻,采集到了A0~A5的電壓制為1023,D2為高電平,D3位低電平,那么應該上傳:
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接口的信息的時候,一個AD接口采集了5次,取五次結果的中間值作為最后上傳的結果:
  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
復制代碼

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

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


在源代碼中,將數據打包上傳的代碼:(Serial.write發送8位無符號整數)
  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.     }
復制代碼

而每隔大約75ms,S4A會將D4~D13的值傳給Arduino。因為這個時間很短,為了保證數據的接受完整,在實際移植的時候,應該建立RingBuffer緩沖區,采用中斷接收的方式。

[原文]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.

當Arduino接收到S4A傳來的數據之后,會對數據解碼,獲取N編號和R的值:
  1.     pin = ((actuatorHighByte >> 3) & 0x0F);
  2.     newVal = ((actuatorHighByte & 0x07) << 7) | (actuatorLowByte & 0x7F);
復制代碼
如果R值需要更新:
  1.     if(arduinoPins[pin].state != newVal)
  2.     {
  3.         arduinoPins[pin].state = newVal;
  4.         updateActuator(pin);
  5.     }
復制代碼
而查閱updateActuator的代碼,發現并沒有更新舵機的代碼(具體什么原因,會和上文提到的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.     }
復制代碼
20ms?
loop函數是整個調用過程:
  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.     }
復制代碼

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

   millis()是Arduino中用于獲取自CPU啟動以來經歷的ms數。將timerCheckUpdate改為0,只不過第一次執行的時候if中的語句也能夠執行罷了。在這20ms中,更新了舵機的數值,上傳了A0~A5,D2,D3的狀態。在最后更新了timerCheckUpdate時間戳,保證下一次執行是在20ms之后。如果這時候串口的接受緩沖區中存在數據,讀出來,并解析。
    先科普一下舵機的知識:舵機的轉動角度是0~180度,轉動角度的大小是由pwm的占空比決定的。pwm的周期必須為20ms。pwm波形中高電平的時間大約在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.     }
復制代碼
servo這個函數將S4A發送來的舵機的轉動角度(0~180)轉換成為實際的高電平時間。然后通過延時來產生一定時間的高電平。為了保證舵機能夠正常運轉。在移植的時候必須提供一個精度較高的delayMicroseconds函數。

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

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

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

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产在线精品一区 | 国产精品入口麻豆www | 欧美日韩视频在线播放 | 久久久久国产视频 | 亚洲精品成人在线 | 91中文字幕在线观看 | 亚洲欧美日韩久久久 | 黄视频在线网站 | 日韩在线视频播放 | 国产成人精品一区二区 | 在线婷婷| 欧美成人精品一区二区男人看 | 欧美综合国产精品久久丁香 | 黄色一级特级片 | 国产91亚洲精品 | 免费观看一级视频 | 欧美一区二区在线免费观看 | 国内成人免费视频 | 日韩视频免费看 | 9191成人精品久久 | 999视频在线播放 | 国产一区二区在线免费视频 | 久久久蜜桃一区二区人 | 欧美一级在线视频 | 久久精品一二三影院 | 欧美综合久久久 | 免费观看黄色片视频 | 中文字幕高清 | 色av一区二区三区 | 97精品超碰一区二区三区 | 久久久国产精品 | 免费看片在线播放 | 免费不卡一区 | 国产在线观看一区二区 | 中文字幕精品一区久久久久 | 久久国产精品一区二区三区 | 亚洲视频免费在线观看 | 伊人网在线综合 | 欧美另类日韩 | 亚洲九色 | 天堂亚洲网 |