ShofEL2, Tegra X1 and Nintendo Switch 사용하기

OS/Linux 2018.04.25 23:29 Posted by 파란크리스마스

원문 출서 - 전체내용

By switch_enthusiast
Filed under switch vulnerability exploit linux

핵심적인 내용만 구글 번역한 내용입니다.

ShofEL2 및 Switch Linux에 오신 것을 환영합니다. 

Nintendo Switch (Tegra X1 플랫폼)에서 fail0verflow의 부트 스택을 수정하지 않고 범용 코드 실행 및 Linux 용으로 사용할 수 있습니다.

exploit(취약점 공격)을 릴리스할지 여부를 선택하는 것은 어려운 선택입니다.

과거의 콘솔에 대한 우리의 경험을 감안할 때, 우리는 본질적으로 해적 행위보다는 해적 행위에 사용될 수 있다는 두려움 때문에 취약성 세부 사항이나 악용 사례를 공개하는 것에 조심했습니다.

즉, Tegra bootrom 버그가 너무 분명해서 여러 사람이 지금까지 독자적으로 발견했습니다.

기껏해야 다른 사생 팀의 석방은 불가피하지만 최악의 경우 특정 해적판 모 듈팀이 첫 번째 조치를 취할 수 있습니다.

90 일 전 Tegra 칩은 Android 기기에서 주로 사용되기 때문에 책임있는 공개 프로세스가 시작되었습니다. 공개 기한이 지났습니다. 버그는 조만간 공개 될 것이며, 우리는 리눅스 부트 체인과 커널 트리와 함께 출시 할 것입니다.

각각은 여러 가지 독립적 인 방식으로 수행 될 수 있습니다. 이것이 iPhone 사용자가 USB를 통해 부팅 할 때마다 수행해야한다는 점에서 "묶인 탈옥"이라고 부르는 것입니다. 이 버그는 부트 ROM에 있기 때문에 하드웨어 개정 없이는 패치 할 수 없습니다. 즉, 현재 존재하는 모든 스위치 유닛은 영원히 취약합니다. Nintendo는 제조 과정 중에 Boot ROM 버그 만 패치 할 수 있습니다. 이 취약점은 부팅 프로세스 초기에 발생하므로 Boot ROM 자체 및 모든 암호화 키를 포함하여 모든 장치 데이터와 암호를 추출 할 수 있습니다. 또한 하드웨어 손상이 없거나 돌이킬 수없는 변경 사항 (예 : 퓨즈 끊김)이없는 한 Tegra 장치를 해제 할 때 사용할 수 있습니다. 그리고 이것은 내장 된 eMMC 스토리지를 만질 필요가없는 부팅 시간 버그이기 때문에 기존 소프트웨어에 대해서는 사용이 완전히 감지되지 않습니다. 온보드 메모리를 변경하려고하지 않는 한, USB 익스플로잇을 통해 리눅스를 부팅하고 (보통의 부팅을 통해) 스위치 OS를 영구적으로 이중 부팅 할 수 있습니다 (예 : 리눅스 파일 시스템 두 번째 SD 카드 파티션 또는 다른 SD 카드).

우리가 재미와 자작 등을 위해이 일을한다는 것을 분명히하기 위해서입니다.


우리가 계획하고있는 것이지만, 90 일 공개 창이 4 월 25 일에 만료되기 2 일 전에 누군가가 0 일 버그를 게시했습니다. 오 잘. 예, 이것은 fusée gelée에서 악용 한 것과 동일한 버그입니다. 다른 일부 그룹이 누출 한 것입니다 (그러나 먼저 발견했습니다).

우리가 blogpost / repos를 준비하지 못했기 때문에 (이것은 우리와 마찬가지로 procrastinators가되었지만) 약간의 어려움이있을 것입니다

What’s this all about anyway?

Nintendo Switch 내부의 Tegra X1 (Tegra210이라고도 함) SoC에는 모든 서명 검사를 우회하여 조기 실행을 제어 할 수있는 악용 가능한 버그가 있습니다. 이 버그는 RCM 모드에서 Tegra 장치를 처음으로 깜박이고 bricked 장치를 복구하기위한 USB 기반 복구 모드입니다. 일반적으로 RCM 모드는 서명 된 이미지 만로드 할 수 있지만 버그로 인해 임의 코드가 실행될 수 있습니다.

즉, 스위치에서 코드를 실행하려면 완전히 독립적 인 두 가지 작업을 수행해야합니다.

  1. Enter RCM mode
  2. Execute the USB-based exploit

Entering RCM mode

  1. 이전 커널 모드 코드 실행
    예 : WebKit 익스플로잇과 커널 익스플로잇을 진입 점으로 사용하기
  2. eMMC가 제거되면, Tegra는 부팅시 RCM 모드로 들어갑니다.
  3. 스위치의 볼륨 높이기, 홈 및 전원 버튼을 동시에 누릅니다.

Joy-Con 홈 단추는 여기에서 작동하지 않습니다. Nintendo 스위치 자체의 비밀 홈 버튼에 대해 궁금 할 것입니다. Tegra가 Home 버튼이라고 부르는 것은 실제로 오른쪽 Joy-Con 커넥터의 핀 10 (가장 왼쪽의 핀)에 연결됩니다. 간단한 철사를 사용하여 예를 들어 철로로 연결할 수 있습니다. 레일에 나사 (가장 쉬운) 또는 핀 10과 7 (또는 1) 함께 (10과 9는 작동하지 않음). Micro USB 커넥터 (Joy-Con 커넥터와 동일한 핀 피치)를 사용하여 작은 지그를 쉽게 인쇄하거나 커넥터의 기증자로 분리 된 Joy-Con을 사용할 수도 있습니다. 조이 콘 (Joy-Con) 레일이 UART이기 때문에 후자가 유용합니다. 우리는 코어 부트, u- 부트 및 리눅스를위한 콘솔로 오른 손잡이 조이 콘 포트를 사용합니다.

Executing the USB-based exploit

USB 악용에는 USB 호스트가 필요합니다. 익스플로잇은 또한 매우 긴 컨트롤 전송을 필요로하는데, 불행하게도 일부 OS는 만족스럽지 않다. xHCI 컨트롤러 (USB 3.0 또는 최신 시스템의 USB 포트)가있는 PC에서 바닐라 Linux를 사용하거나 EHCI (USB 2.0) 컨트롤러 및이 커널 패치가있는 PC를 사용할 수 있습니다. 이것은 안드로이드 폰 (적어도 xHCI 컨트롤러를 가진 사람들)에서도 실행될 수 있습니다. 안드로이드에 대한 익스플로잇 포팅은 독자에게 운동으로 남아 있습니다. 다른 Tegra 장치에서 그것을하기위한 보너스 포인트. 다른 스위치처럼.

Linux on Switch boot chain

우리의 부트 체인은 Pixel C 부트 체인을 기반으로하는 99 % 오픈 소스입니다.

(누가 Nvidia의 지저분한 L4T 커널 포크와 독점적 인 부트 로더를 사용하기를 원합니까?).

다음과 같이 보입니다.

BootROM Exploit → coreboot 로더 → coreboot → ARM 트러스트 된 펌웨어 → coreboot → u-boot → Linux

선택적으로 제공되는 유일한 폐쇄 소스 구성 요소는 Tegra210 DDR4 메모리 교육 코드입니다. 알려지지 않은 이유로 Pixel C의 바이너리 블롭 (blob)으로 릴리즈됩니다. Pixel C는 메모리로 복사되어 점프됩니다. 이 얼룩은 Pixel C 팩토리 이미지에서 다음과 같이 얻을 수 있습니다.

./build/util/cbfstool/cbfstool bootloader-dragon-google_smaug.7900.97.0.img extract -n fallback/tegra_mtc -f tegra_mtc.bin

이 BLOB에는 하드 코딩 된 테이블과 픽셀 C에 대한 "모든 것을 수행"진입 점이 포함되어 있지만 호출 트리 깊숙한 한 수준으로 건너 뛰고 사용자 정의 테이블을 전달할 수 있습니다.

이는 우리의 패치 된 coreboot가 스위치에서 DDR4를 구성하기 위해 수행하는 작업입니다. 이 얼룩이 없다면 스택은 여전히 ​​작동 할 것이지만, 메모리는 ~ 200Mhz에서 실행될 것이고 불필요한 성능은 절름발이입니다.

부팅 프로세스는 다음과 같습니다.

  1. Tegra는 BPMP (arm7) 코어에서 부트 ROM을 시작하고 RCM 모드로 들어갑니다.
  2. 호스트 기반 USB 익스플로잇 코드는 RCM 명령을 사용하여 작은 (~ 2.5K) 로더 (cbfs.bin)를 SRAM 메모리에 저장합니다.
  3. 익스플로잇이 트리거되어 ROM이 cbfs.bin으로 점프합니다.
  4. 그런 다음 호스트 코드는 CBFS 서버 모드로 들어가고 USB RCM 파이프를 통해 Tegra에 코어 부트 (coreboot)를 동적으로 제공합니다.
  5. cbfs.bin은이 CBFS 서버를 사용하여 coreboot 부트 블럭 인 coreboot의 첫 번째 28KiB를 SRAM에 요청한 다음 그 내용으로 이동합니다.
  6. 코어 부트 (coreboot) 부트 블럭은 기본 주변 장치를 초기화 한 다음 USB의 CBFS 서비스를 사용하여 롬 스테이지를 SRAM으로로드하고 점프합니다.
  7. coreboot romstage는 SDRAM (기본 고정 부팅 속도) 및 기타 주변 장치를 초기화합니다.
  8. 그런 다음 romstage는 전체 coreboot ROM을 SDRAM (여전히 부트 ROM RCM 모드 USB 루틴 사용)으로 다운로드하고 RAM 기반 CBFS로 전환합니다.
  9. 이제 romstage는 RAM CBFS에서 램 스테이지를로드하고 CCPLEX (Cortex-A57)를 시작하고 BPMP를 종료합니다.
  10. 이제 CCPLEX (EL3)에서 coreboot ramstage는 MTC BLOB를 사용할 수있는 경우 DDR4 교육을 포함하여 나머지 기본 시스템 초기화를 수행합니다.
  11. 이제 램 스테이지는 TrustZone 구현을 초기화하는 ARM 트러스티 드 펌웨어로 이동합니다. 이는 특정 OS 서비스를 제공하는 데 필요합니다.
  12. ARM Trusted Firmware는 이제 EL2 모드에서 실행되는 코어 부트 람시 (coreboot ramstage)로 돌아갑니다.
  13. 낙담은 최종 유료 하중 인 U-Boot로로드되어 점프합니다.
  14. U-Boot가 시작되고, 더 많은 하드웨어를 초기화하며, 기본적으로 자체 USB 드라이버를 사용하여 USB 다운로드 모드로 들어갑니다.
  15. PC 측에서 imx_usb_loader를 사용하면 Linux 커널과 initramfs와 같은 임의의 U-Boot 페이로드를로드하여 실행할 수 있습니다.

The code

  • https://github.com/fail0verflow/shofel2
  • https://github.com/fail0verflow/switch-arm-trusted-firmware
  • https://github.com/fail0verflow/switch-coreboot
  • https://github.com/fail0verflow/switch-u-boot
  • https://github.com/fail0verflow/switch-linux

죄송합니다. 일반 사용자가이 도구를 사용하는 데 필요한 안내서가 없으며 가장자리에 많은 것들이 너무 거칠어도 안됩니다. 개발에 진지한 사람이라면 스스로 생각하거나 IRC에 질문 할 수 있어야합니다.

우리는 Git 이력을 정리할 시간이 없었기 때문에 Git 이력은 지져분합니다. 너무 열심히 읽지 마십시오.

Coming soon

Proper write-up on the exploit, stories of porting Linux (yes, there’s more to it than a panel driver ;-) ), upstreaming status, how batshit insane DDR4 is, and more. Probably, anyway. We’re pretty bad at writing blogposts. 

 ¹ There are actually many Boot ROM bugs, several of which have been found by multiple people.

micro:bit - pxt 설치(오프라인 블럭 컴파일러 구축)

OS/micro:bit 2018.04.07 22:45 Posted by 파란크리스마스

출처

pxt 관련 라이브러리 설치

D:\microbit>npm install -g jake
C:\Users\bluesanta\AppData\Roaming\npm\jake -> C:\Users\bluesanta\AppData\Roaming\npm\node_modules\jake\bin\cli.js
+ jake@8.0.16
added 13 packages in 2.485s

D:\microbit>npm install -g typings
npm WARN deprecated typings@2.1.1: Typings is deprecated in favor of NPM @types -- see README for more information
C:\Users\bluesanta\AppData\Roaming\npm\typings -> C:\Users\bluesanta\AppData\Roaming\npm\node_modules\typings\dist\bin.js
+ typings@2.1.1
added 183 packages in 12.988s

pxt 다운로드

D:\microbit>git clone https://github.com/microsoft/pxt
Cloning into 'pxt'...
remote: Counting objects: 52887, done.
remote: Compressing objects: 100% (424/424), done.
remote: Total 52887 (delta 311), reused 324 (delta 173), pack-reused 52279
Receiving objects: 100% (52887/52887), 131.47 MiB | 197.00 KiB/s, done.
Resolving deltas: 100% (37029/37029), done.

D:\microbit>cd pxt

D:\microbit\pxt>git checkout v0
Switched to a new branch 'v0'
Branch 'v0' set up to track remote branch 'v0' from 'origin'.

pxt 설치

D:\microbit\pxt>npm install npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.3 (node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) added 115 packages in 12.661s D:\microbit\pxt>typings install D:\microbit\pxt>jake D:\microbit\pxt>cd ../ D:\microbit>

pxt-microbit 설치

D:\microbit>git clone https://github.com/microsoft/pxt-microbit
D:\microbit>cd pxt-microbit
D:\microbit\pxt-microbit>npm install -g pxt
D:\microbit\pxt-microbit>npm install
D:\microbit\pxt-microbit>npm link ../pxt
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

added 115 packages in 21.441s
C:\server\node-v8.9.1-win-x64\node_modules\pxt-core -> D:\microbit\pxt
D:\microbit\pxt-microbit\node_modules\pxt-core -> C:\server\node-v8.9.1-win-x64\node_modules\pxt-core -> D:\microbit\pxt

pxt 서버 실행

(workspace) D:\>mkdir pxtsrc

(workspace) D:\>cd pxtsrc

(workspace) D:\pxtsrc>pxt target microbit
Installing pxt-microbit locally; don't worry about package.json warnings.

> keytar@4.2.1 install D:\pxtsrc\node_modules\keytar
> prebuild-install || node-gyp rebuild

prebuild-install info begin Prebuild-install version 2.5.1
prebuild-install info looking for local prebuild @ prebuilds\keytar-v4.2.1-node-v57-win32-x64.tar.gz
prebuild-install info looking for cached prebuild @ C:\Users\bluesanta\AppData\Roaming\npm-cache\_prebuilds\https-github.com-atom-node-keytar-releases-download-v4.2.1-keytar-v4.2.1-node-v57-win32-x64.tar.gz
prebuild-install info found cached prebuild
prebuild-install info unpacking @ C:\Users\bluesanta\AppData\Roaming\npm-cache\_prebuilds\https-github.com-atom-node-keytar-releases-download-v4.2.1-keytar-v4.2.1-node-v57-win32-x64.tar.gz
prebuild-install info unpack resolved to D:\pxtsrc\node_modules\keytar\build\Release\keytar.node
prebuild-install info unpack required D:\pxtsrc\node_modules\keytar\build\Release\keytar.node successfully
prebuild-install info install Successfully installed prebuilt binary!

> node-hid@0.5.7 install D:\pxtsrc\node_modules\node-hid
> prebuild-install || node-gyp rebuild

prebuild-install info begin Prebuild-install version 2.5.1
prebuild-install info looking for local prebuild @ prebuilds\node-hid-v0.5.7-node-v57-win32-x64.tar.gz
prebuild-install info looking for cached prebuild @ C:\Users\bluesanta\AppData\Roaming\npm-cache\_prebuilds\https-github.com-node-hid-node-hid-releases-download-v0.5.7-node-hid-v0.5.7-node-v57-win32-x64.tar.gz
prebuild-install info found cached prebuild
prebuild-install info unpacking @ C:\Users\bluesanta\AppData\Roaming\npm-cache\_prebuilds\https-github.com-node-hid-node-hid-releases-download-v0.5.7-node-hid-v0.5.7-node-v57-win32-x64.tar.gz
prebuild-install info unpack resolved to D:\pxtsrc\node_modules\node-hid\build\Release\HID.node
prebuild-install info unpack required D:\pxtsrc\node_modules\node-hid\build\Release\HID.node successfully
prebuild-install info install Successfully installed prebuilt binary!

> serialport@6.1.1 install D:\pxtsrc\node_modules\serialport
> prebuild-install || node-gyp rebuild

prebuild-install info begin Prebuild-install version 2.5.1
prebuild-install info looking for local prebuild @ prebuilds\serialport-v6.1.1-node-v57-win32-x64.tar.gz
prebuild-install info looking for cached prebuild @ C:\Users\bluesanta\AppData\Roaming\npm-cache\_prebuilds\https-github.com-node-serialport-node-serialport-releases-download-v6.1.1-serialport-v6.1.1-node-v57-win32-x64.tar.gz
prebuild-install info found cached prebuild
prebuild-install info unpacking @ C:\Users\bluesanta\AppData\Roaming\npm-cache\_prebuilds\https-github.com-node-serialport-node-serialport-releases-download-v6.1.1-serialport-v6.1.1-node-v57-win32-x64.tar.gz
prebuild-install info unpack resolved to D:\pxtsrc\node_modules\serialport\build\Release\serialport.node
prebuild-install info unpack required D:\pxtsrc\node_modules\serialport\build\Release\serialport.node successfully
prebuild-install info install Successfully installed prebuilt binary!
npm WARN saveError ENOENT: no such file or directory, open 'D:\pxtsrc\package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open 'D:\pxtsrc\package.json'
npm WARN pxtsrc No description
npm WARN pxtsrc No repository field.
npm WARN pxtsrc No README data
npm WARN pxtsrc No license field.

+ pxt-microbit@0.14.30
added 384 packages in 15.705s
Installed PXT/microbit. To start server run:
    pxt serve

(workspace) D:\pxtsrc>pxt serve
Using target PXT/microbit with build engine yotta
  Target dir:   D:\pxtsrc\node_modules\pxt-microbit
  PXT Core dir: D:\pxtsrc\node_modules\pxt-core
Invalid accessToken format, expecting something like 'https://example.com/?access_token=0abcd.XXXX'
Going to D:\pxtsrc\node_modules\pxt-microbit
No sim/tsconfig.json; assuming npm installed package
Starting server in D:\pxtsrc\node_modules\pxt-microbit
With pxt core at D:\pxtsrc\node_modules\pxt-core
starting local ws server at 3233...
serial: monitoring ports...
---------------------------------------------

To launch the editor, open this URL:
http://localhost:3232/#local_token=452b727d-6d77-4d83-98d5-0bdab305f72e&wsport=3233

---------------------------------------------
opening http://localhost:3232/#local_token=452b727d-6d77-4d83-98d5-0bdab305f72e&wsport=3233

프로젝트 생성

D:\pxtsrc\projects>mkdir pxt-ultrasonic-microbit

D:\pxtsrc\projects>cd pxt-ultrasonic-microbit

D:\pxtsrc\projects\pxt-ultrasonic-microbit>pxt init
Using target PXT/microbit with build engine yotta
  Target dir:   D:\pxtsrc\node_modules\pxt-microbit
  PXT Core dir: D:\pxtsrc\node_modules\pxt-core
Invalid accessToken format, expecting something like 'https://example.com/?access_token=0abcd.XXXX'
name [ultrasonic-microbit]:
description []:
license [MIT]:
skipping download of local pkg: file:.
Package initialized.
Try 'pxt add' to add optional features.

D:\pxtsrc\projects\pxt-ultrasonic-microbit>code .

빌드

Raspberry Pi - Qt5 설치

OS/Raspberry Pi 2018.04.04 23:09 Posted by 파란크리스마스

출처

Qt5 설치

$ sudo apt-get update
$ sudo apt-get install qt5-default qtbase5-dev qtdeclarative5-dev qt5-qmake qtcreator libqt5gui5  qtscript5-dev qtmultimedia5-dev libqt5multimedia5-plugins qtquickcontrols2-5-dev libqt5network5 cmake build-essential 
$ sudo apt-get install libqt5svg5-dev

oscpack 라이브러리

oscpack 라이브러리 다운로드

$ git clone https://github.com/dimitry-ishenko-casparcg/oscpack.git
Cloning into 'oscpack'...
remote: Counting objects: 511, done.
remote: Total 511 (delta 0), reused 0 (delta 0), pack-reused 511
Receiving objects: 100% (511/511), 110.97 KiB | 0 bytes/s, done.
Resolving deltas: 100% (377/377), done.

oscpack 라이브러리 설치

$ cd oscpack
$ make
$ sudo make install
install -c -D -m 755 liboscpack.so.1.1.0 //usr/local/lib/liboscpack.so.1.1.0
ln -s -f liboscpack.so.1.1.0 //usr/local/lib/liboscpack.so
mkdir -p //usr/local/include/ip //usr/local/include/osc
install -c -D -m 644 ip/*.h //usr/local/include/ip
install -c -D -m 644 osc/*.h //usr/local/include/osc
SUCCESS! oscpack has been installed in //usr/local/lib and //usr/local/include/ospack/

QT예제 - timer 프로그램

timer 프로그램 컴파일

$ git clone https://github.com/dimitry-ishenko-casparcg/timer.git
$ cd timer
$ qmake
$ ls
Makefile  README.md  res  screenshot.png  src  timer.pro
$ make

timer 프로그램 실행

$ ./timer

micro:bit - 라인 트레이서(Line Trace Sensor)

OS/micro:bit 2018.03.18 17:01 Posted by 파란크리스마스

출처 : Motor Driver Board for the BBC micro:bit - V2 | Kitronik
Blog Yamasho: Delphi 10.2.2:Bleで Microbitと通信する。
googlesamples/android-BluetoothLeGatt - GitHub
ButtonService - micro:bit runtime
microbit-samples/source/examples/bluetooth-services/main.cpp - GitHub
https://github.com/lancaster-university/microbit-dal/issues/337
Advanced - micro:bit runtime - GitHub Pages
Send/Receive Data Using BLE and MBED | BBC:Microbit - Instructables

micro:bit - 라인 트레이서(Line Trace Sensor)

라인트레이서 센서와 초음파 거리센서(HC-SR04)를 이용해서 라인을 따라서 가면서 장애물이 있으면 멈추는 RC카를 구현했습니다.

소스

#include "MicroBit.h"
#include "MicroBitSerial.h"
#include "hcsr04.h"

//MicroBit uBit;
MicroBitSerial serial(USBTX, USBRX);
HCSR04 usensor(P0_0, P0_30); // P0_0 TRIGGER P0_30 ECHO
unsigned int dist;

//
// P0_1, P0_26, P0_17 성공 - line
// P0_18, P0_20, P0_3, P0_16 - moter

//AnalogIn ain(P0_3);
DigitalIn LINE_T1(P0_1);
DigitalIn LINE_T2(P0_23);
DigitalIn LINE_T3(P0_21);
DigitalIn LINE_T4(P0_22);

int main() {
	//uBit.init();
	//uBit.display.scroll("init", 70);
	serial.printf("init : \r\n");
	 
	while(1) {
		usensor.start();
		wait_ms(500);
		dist = usensor.get_dist_cm();
		serial.printf("-------------------------\r\n d:%d\r\n", dist);
		
		/*
		float x = ain.read();
		int aa = (int)(x *  1000);
		serial.printf("%d \r\n", aa);
		*/

		serial.printf("1:%d - ", LINE_T1.read());
		serial.printf("2:%d - ", LINE_T2.read());
		serial.printf("3:%d - ", LINE_T3.read());

		if (LINE_T4 == 1) {
			serial.printf("4:1\r\n");
		} else {
			serial.printf("4:0\r\n");
		}
	}
}

콘솔 로그

소스 - micro:bit - RC Car - Line Trace Sensor

source.zip

#include "MicroBit.h"
#include "MicroBitSerial.h"
#include "hcsr04.h"

MicroBit uBit;
//MicroBitSerial serial(USBTX, USBRX);
HCSR04 usensor(P0_3, P0_2); // P0_0 TRIGGER P0_30 ECHO
unsigned int dist;

//
// P0_1, P0_26, P0_17 성공 - line
// P0_18, P0_20, P0_3, P0_16 - moter

//AnalogIn ain(P0_3);
DigitalIn LINE_T1(P0_1);
DigitalIn LINE_T2(P0_23);
DigitalIn LINE_T3(P0_21);
DigitalIn LINE_T4(P0_22);

#define MOTER_LOW            0
#define MOTER_HIGH           0.32 // 스피드 - 0 ~ 1 | 최대속도 = 1
 
PwmOut moter_right_front(P0_18);    //12 - right
PwmOut moter_right_back(P0_20);     //8
PwmOut moter_left_front(P0_3);      //16 - left
PwmOut moter_left_back(P0_16);          //0
 
//모터A,B 정회전
void bothMotorStart()
{
  moter_right_front = MOTER_HIGH;
  moter_right_back = MOTER_LOW;
  moter_left_front = MOTER_HIGH;
  moter_left_back = MOTER_LOW;
}
  
//모터A,B 역회전
void bothMotorBack()
{
  moter_right_front = MOTER_LOW;
  moter_right_back = MOTER_HIGH;
  moter_left_front = MOTER_LOW;
  moter_left_back = MOTER_HIGH;
}
    
//모터A,B Stop
void stopAllMotor()
{
  moter_right_front = MOTER_LOW;
  moter_right_back = MOTER_LOW;
  moter_left_front = MOTER_LOW;
  moter_left_back = MOTER_LOW;
}
    
//모터A 역회전, 모터B 정회전
void turnLeft()
{
  moter_right_front = MOTER_LOW;
  moter_right_back = MOTER_HIGH;
  moter_left_front = MOTER_HIGH;
  moter_left_back = MOTER_LOW;
}
    
//모터A 정회전, 모터B 역회전
void turnRight()
{
  moter_right_front = MOTER_HIGH;
  moter_right_back = MOTER_LOW;
  moter_left_front = MOTER_LOW;
  moter_left_back = MOTER_HIGH;
}
    
//모터A 정회전, 모터B Stop
void motorA_Rotation()
{
  moter_right_front = MOTER_HIGH;
  moter_right_back = MOTER_LOW;
  moter_left_front = MOTER_LOW;
  moter_left_back = MOTER_LOW;
}
    
//모터A Stop, 모터B 정회전
void motorB_Rotation()
{
  moter_right_front = MOTER_LOW;
  moter_right_back = MOTER_LOW;
  moter_left_front = MOTER_HIGH;
  moter_left_back = MOTER_LOW;
}
    
//모터A 역회전, 모터B Stop
void motorA_Reverse()
{
  moter_right_front = MOTER_LOW;
  moter_right_back = MOTER_HIGH;
  moter_left_front = MOTER_LOW;
  moter_left_back = MOTER_LOW;
}
    
//모터A Stop, 모터B 역회전
void motorB_Reverse()
{
  moter_right_front = MOTER_LOW;
  moter_right_back = MOTER_LOW;
  moter_left_front = MOTER_LOW;
  moter_left_back = MOTER_HIGH;
}

int main() {
	uBit.init();
	uBit.display.scroll("init", 70);
	uBit.serial.printf("init : \r\n");
	 
	while(1) {
		usensor.start();
		wait_ms(50);
		dist = usensor.get_dist_cm();
		uBit.serial.printf("-------------------------\r\n d:%d\r\n", dist);
		uBit.serial.printf("%d, %d, %d, %d\r\n", LINE_T1.read(),LINE_T2.read(),LINE_T3.read(),LINE_T4.read());

		if (dist <= 10) {
			stopAllMotor();
		} else {
			if (LINE_T2 == 1 || LINE_T3 == 1) {
				bothMotorStart();
			} else if (LINE_T1 == 1) {
				turnRight();
			} else if (LINE_T4 == 1) {
				turnLeft();
			} else {
				bothMotorStart();
			}
		}

	}
}

micro:bit - RC Car - Line Trace Sensor

micro:bit - 초음파 거리센서(HC-SR04)

OS/micro:bit 2018.03.15 00:18 Posted by 파란크리스마스

출처 : Steve136/microbit-ultrasonic: Example usage of a HC-SR04 Ultrasonic Sensor and the BBC Micro:Bit.
HCSR04 - Ultrasound Ranging Sensor module | Mbed

micro:bit - 초음파 거리센서(HC-SR04)

 

소스

#include "MicroBit.h"
#include "hcsr04.h"

MicroBit uBit;
HCSR04 usensor(P0_3, P0_2); // TRIGGER, ECHO
unsigned int dist;

int main() {
	uBit.init();
	uBit.display.scroll("init", 70);
	
	while(1) {
		usensor.start();
		wait_ms(500); 
		dist = usensor.get_dist_cm();
		
		char buf[100];
		sprintf (buf, "d:%d", dist);
		uBit.display.scroll(buf, 70);
		wait(1.0); // 1 sec  
	}
}

micro:bit - SD Card File 생성 및 쓰기

OS/micro:bit 2018.02.25 20:56 Posted by 파란크리스마스

출처 : SD Card File System - Cookbook | Mbed
FATFileSystem - FATFileSystem | Mbed

micro:bit - SD Card File 생성 및 쓰기

SD Card File System와 FATFileSystem 라이브러리를 사용해서 micro:bit에서 마이크로 SD에 파일 쓰기 예제를 만들어 보았습니다.
Microsoft Block용 라이브러리인 pxt-microsd-microbit도 공개 되어 있으니 참고 하세요.

소스

#include "MicroBit.h"
#include "SDFileSystem.h"

MicroBit uBit;

SDFileSystem sd(P0_21, P0_22, P0_23, P0_16, "sd"); // mosi, miso, sclk, cs

int main() {
	//uBit.init();
	
	//디렉토리 생성
	//mkdir("/sd/mydir", 0777);
	
	// 파일 열기
	FILE *fp = fopen("/sd/microbit.txt", "w");
	if(fp == NULL) {
		error("Could not open file for write\n");
	}
	// 파일 쓰기
	fprintf(fp, "Hello World!\n");
	// 파일 닫기
	fclose(fp);
}

micro:bit - 이벤트

OS/micro:bit 2018.02.24 11:32 Posted by 파란크리스마스

MicroBitRadioEvent.h

    /**
      * Associates the given event with the radio channel.
      *
      * Once registered, all events matching the given registration sent to this micro:bit's
      * default EventModel will be automatically retransmitted on the radio.
      *
      * @param id The id of the event to register.
      *
      * @param value the value of the event to register.
      *
      * @return MICROBIT_OK on success, or MICROBIT_NO_RESOURCES if no default EventModel is available.
      *
      * @note The wildcards MICROBIT_ID_ANY and MICROBIT_EVT_ANY can also be in place of the
      *       id and value fields.
      */
    int listen(uint16_t id, uint16_t value);

    /**
      * Associates the given event with the radio channel.
      *
      * Once registered, all events matching the given registration sent to the given
      * EventModel will be automatically retransmitted on the radio.
      *
      * @param id The id of the events to register.
      *
      * @param value the value of the event to register.
      *
      * @param eventBus The EventModel to listen for events on.
      *
      * @return MICROBIT_OK on success.
      *
      * @note The wildcards MICROBIT_ID_ANY and MICROBIT_EVT_ANY can also be in place of the
      *       id and value fields.
      */
    int listen(uint16_t id, uint16_t value, EventModel &eventBus);

MicroBitMessageBus.cpp

/**
  * Queues the given event to be sent to all registered recipients.
  *
  * @param evt The event to send.
  *
  * @code
  * MicroBitMessageBus bus;
  *
  * // Creates and sends the MicroBitEvent using bus.
  * MicrobitEvent evt(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK);
  *
  * // Creates the MicrobitEvent, but delays the sending of that event.
  * MicrobitEvent evt1(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, CREATE_ONLY);
  *
  * bus.send(evt1);
  *
  * // This has the same effect!
  * evt1.fire()
  * @endcode
  */
int MicroBitMessageBus::send(MicroBitEvent evt)
{
    // We simply queue processing of the event until we're scheduled in normal thread context.
    // We do this to avoid the possibility of executing event handler code in IRQ context, which may bring
    // hidden race conditions to kids code. Queuing all events ensures causal ordering (total ordering in fact).
    this->queueEvent(evt);
    return MICROBIT_OK;
}

MicroBitFiber.cpp

/**
  * Blocks the calling thread until the specified event is raised.
  * The calling thread will be immediateley descheduled, and placed onto a
  * wait queue until the requested event is received.
  *
  * @param id The ID field of the event to listen for (e.g. MICROBIT_ID_BUTTON_A)
  *
  * @param value The value of the event to listen for (e.g. MICROBIT_BUTTON_EVT_CLICK)
  *
  * @return MICROBIT_OK, or MICROBIT_NOT_SUPPORTED if the fiber scheduler is not running, or associated with an EventModel.
  *
  * @code
  * fiber_wait_for_event(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK);
  * @endcode
  *
  * @note the fiber will not be be made runnable until after the event is raised, but there
  * are no guarantees precisely when the fiber will next be scheduled.
  */
int fiber_wait_for_event(uint16_t id, uint16_t value)
{
    int ret = fiber_wake_on_event(id, value);

    if(ret == MICROBIT_OK)
        schedule();

	return ret;
}

/**
  * Configures the fiber context for the current fiber to block on an event ID
  * and value, but does not deschedule the fiber.
  *
  * @param id The ID field of the event to listen for (e.g. MICROBIT_ID_BUTTON_A)
  *
  * @param value The value of the event to listen for (e.g. MICROBIT_BUTTON_EVT_CLICK)
  *
  * @return MICROBIT_OK, or MICROBIT_NOT_SUPPORTED if the fiber scheduler is not running, or associated with an EventModel.
  *
  * @code
  * fiber_wake_on_event(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK);
  *
  * //perform some time critical operation.
  *
  * //deschedule the current fiber manually, waiting for the previously configured event.
  * schedule();
  * @endcode
  */
int fiber_wake_on_event(uint16_t id, uint16_t value)
{
    Fiber *f = currentFiber;

	if (messageBus == NULL || !fiber_scheduler_running())
		return MICROBIT_NOT_SUPPORTED;

    // Sleep is a blocking call, so if we're in a fork on block context,
    // it's time to spawn a new fiber...
    if (currentFiber->flags & MICROBIT_FIBER_FLAG_FOB)
    {
        // Allocate a TCB from the new fiber. This will come from the tread pool if availiable,
        // else a new one will be allocated on the heap.
        forkedFiber = getFiberContext();

        // If we're out of memory, there's nothing we can do.
        // keep running in the context of the current thread as a best effort.
        if (forkedFiber != NULL)
        {
            f = forkedFiber;
            dequeue_fiber(f);
            queue_fiber(f, &runQueue);
            schedule();
        }
    }

    // Encode the event data in the context field. It's handy having a 32 bit core. :-)
    f->context = value << 16 | id;

    // Remove ourselves from the run queue
    dequeue_fiber(f);

    // Add ourselves to the sleep queue. We maintain strict ordering here to reduce lookup times.
    queue_fiber(f, &waitQueue);

    // Register to receive this event, so we can wake up the fiber when it happens.
    // Special case for the notify channel, as we always stay registered for that.
    if (id != MICROBIT_ID_NOTIFY && id != MICROBIT_ID_NOTIFY_ONE)
        messageBus->listen(id, value, scheduler_event, MESSAGE_BUS_LISTENER_IMMEDIATE);

    return MICROBIT_OK;
}

이벤트 메소드 구현

void onButtonA(MicroBitEvent e)
{
  uBit.display.scroll("A");
}

리스너 등록

  // listen for user button interactions
  uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, onButtonA);
  uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonB);
  uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, onButtonAB);

micro:bit - ESP8266 ESP-01 Serial Wireless WIFI Module

OS/micro:bit 2018.02.23 23:31 Posted by 파란크리스마스

출처 : micro:bit IoT In C - Getting On WiFi

micro:bit - ESP8266 ESP-01 Serial Wireless WIFI Module

pulse-combined.hex

micro:bit의 한가지 아쉬운 점은 Wifi가 내장되어 있지 않아 Wifi를 따로 설치해야 되는데, 이번에 아두이노에서 많이 사용하는 Wifi 모듈인 ESP8266을 사용해서 공유기에 접속하고 간단하게 웹서비스로 온도를 제공하는 서비스를 구현했습니다. 

결과는 PC 브라우져로 접속하면 결과를 확인 해볼 수 있습니다.

배선

핀 배열

  1. Ground - connect to ground 
  2. TXO - the serial tx pin 
  3. GPIO2 - ignore 
  4. CHPD - chip enable connect to 3.3V 
  5. GPIO0 - ignore 
  6. RST - reset leave unconnected 
  7. RXI - the serial rx pin 
  8. VDD - Supply voltage connect to 3.3V

소스

#include "MicroBit.h" 

MicroBit uBit;

void initWiFi();
int ATWiFi();
int resetWiFi();
int setUARTWiFi();
int scanWiFi();
int getIPWiFi(); 
int modeWiFi(int mode);
int connectWiFi(ManagedString ssid, ManagedString pass); int getWebPageWiFi(ManagedString URL, ManagedString page); 
int getVersionWiFi(); 
int startServerWiFi(); 
int waitForWiFi(ManagedString target, int retry, int pause);
int find(ManagedString c, ManagedString s);
void debug(ManagedString s);

#define Tx MICROBIT_PIN_P0 
#define Rx MICROBIT_PIN_P1 
#define DEBUG 1

int main() { 
	uBit.init();
	initWiFi();
	modeWiFi(1);
	connectWiFi("ssid", "password");
	getIPWiFi();
	startServerWiFi();
	release_fiber();
}

void initWiFi() { 
	uBit.serial.redirect(Tx, Rx);
	uBit.serial.baud(115200);
	uBit.serial.setRxBufferSize(500);
}

int ATWiFi() {
	uBit.serial.send("AT\r\n", SYNC_SPINWAIT);
	return waitForWiFi("OK", 150, 10); 
}

int getVersionWiFi() {
	uBit.serial.send("AT+GMR\r\n", SYNC_SPINWAIT);
	return waitForWiFi("OK", 200, 10);
}

int resetWiFi() { 
	uBit.serial.send("AT+RST\r\n", SYNC_SPINWAIT);
	return waitForWiFi("OK", 1000, 10);
}

int setUARTWiFi() { 
	uBit.serial.send("AT+UART_CUR=115200,8,1,0,0\r\n", SYNC_SPINWAIT);
	return waitForWiFi("OK", 200, 10);
}

int scanWiFi() {
	uBit.serial.send("AT+CWLAP\r\n", SYNC_SPINWAIT);
	return waitForWiFi("OK", 500, 50);
}

int modeWiFi(int mode) {
	ManagedString cmd = "AT+CWMODE_CUR=" + ManagedString(mode) + "\r\n";
	uBit.serial.send(cmd, SYNC_SPINWAIT);
	return waitForWiFi("OK", 200, 10); 
}

int connectWiFi( ManagedString ssid, ManagedString pass) { 
	ManagedString cmd = "AT+CWJAP_CUR=\"" + ssid + "\",\"" + pass + "\"\r\n";
	uBit.serial.send(cmd, SYNC_SPINWAIT);
	return waitForWiFi("OK", 200, 20);
}

int getIPWiFi() {
	uBit.serial.send("AT+CIFSR\r\n", SYNC_SPINWAIT);
	return waitForWiFi("OK", 200, 10);
}

int getWebPageWiFi(ManagedString URL, ManagedString page) {
	ManagedString cmd = "AT+CIPSTART=\"TCP\",\"" + URL + "\",80\r\n";
	uBit.serial.send(cmd, SYNC_SPINWAIT);
	
	if (waitForWiFi("OK", 100, 20) == 0) 
		return 0;
		
	ManagedString http = "GET " + page + " HTTP/1.0\r\nHost:" + URL + "\r\n\r\n";
	cmd = "AT+CIPSEND=" +  ManagedString(http.length()) + "\r\n"; 
	uBit.serial.send(cmd, SYNC_SPINWAIT); 
	
	int retry; 
	ManagedString s;
	s = "";
	retry = 40;
	
	do {
		uBit.sleep(100);
		s = s + uBit.serial.read(500, ASYNC); 
		retry--;
	} while (find(">", s) == 0 && retry != 0);
	
	uBit.serial.send(http, SYNC_SPINWAIT);
	retry = 100; 
	
	do { 
		uBit.sleep(100);
		s = s + uBit.serial.read(500, ASYNC);
		retry--;
	} while (s.length() < 500 && retry != 0);
	
	if (DEBUG)debug("\n\rPage\n\r" + s + "\n\r");
	return 1; 
}

int startServerWiFi() {  
	uBit.serial.send("AT+CIPMUX=1\r\n", SYNC_SPINWAIT);
	if (waitForWiFi("OK", 100, 20) == 0) return 0; 
	uBit.serial.send("AT+CIPSERVER=1,80\r\n", 
	                                  SYNC_SPINWAIT);
	if (waitForWiFi("OK", 100, 20) == 0) return 0;
	ManagedString s;
	for (;;) {
		s="";
		do {
		 uBit.sleep(100);
		 if(s>500)s=""; 
		 s = uBit.serial.read(500, ASYNC);
		} while (find("+IPD", s) == 0);
	
		if (DEBUG)debug("\n\rClient Connected\n\r" + s + "\n\r");
			
		int b = find("+IPD", s);
		s = s.substring(b + 1, s.length());
		b = find(",", s); 
		s = s.substring(b + 1, s.length());
		b = find(",", s);
		ManagedString id = s.substring(0, b);
		
		if (DEBUG)debug("\n\rTCP id:" + id + "\n\r"); 
			
		ManagedString headers = "HTTP/1.0 200 OK\r\n";
		headers = headers + "Server: micro:bit\r\n"; 
		headers = headers + "Content-type: text/html\r\n\r\n";
		// ManagedString html = "<html><head><title>Temperature</title></head><body>{\"humidity\":82%,\"airtemperature\":23.5C}</p></body></html>\r\n";
		
		char html [100];
		sprintf (html, "<html><head><title>Temperature</title></head><body>{\"airtemperature\":%dC}</p></body></html>\r\n", uBit.thermometer.getTemperature());
		
		//ManagedString html = buffer;
		ManagedString data = headers + html;
		ManagedString cmd = "AT+CIPSEND=" + id + "," + ManagedString(data.length()) + "\r\n";
		uBit.serial.send(cmd, SYNC_SPINWAIT);
		
		s = "";
		int retry = 40;
		
		do {
			uBit.sleep(100);
			s = s + uBit.serial.read(500, ASYNC);
			retry--;
		} while (find(">", s) == 0 && retry != 0);
	
		uBit.serial.send(data, SYNC_SPINWAIT);
		if (waitForWiFi("OK", 100, 100) == 0) return 0;
			
		if (DEBUG)debug("\n\rData Sent\n\r");
			
		cmd = "AT+CIPCLOSE=" + id + "\r\n"; 
		uBit.serial.send(cmd, SYNC_SPINWAIT);
		if (waitForWiFi("OK", 100, 100) == 0) return 0;
	}
}

void debug(ManagedString s) {
	uBit.serial.redirect(USBTX, USBRX);
	uBit.serial.send(s, SYNC_SPINWAIT);
	uBit.serial.redirect(Tx, Rx);
}

int find(ManagedString c, ManagedString s) {
	int i; 
	for (i = 0; i < (s.length() - c.length()); i++) {
		if (c == s.substring(i, c.length())) break; 
	}
	if (i == (s.length() - c.length())) return 0;
	return i; 
}

int waitForWiFi(ManagedString target, int retry, int pause) {
	ManagedString s;
	do { 
		uBit.sleep(pause);
		if(s.length()>500)s="";
		s = s + uBit.serial.read(500, ASYNC); retry--;
	} while (find(target, s) == 0 && retry != 0);
	
	if (DEBUG)debug("\n\r" + s + "\n\r");
	return retry;
}

실행 - 콘솔 로그

실행결과 - 브러우저에서 확인

micro:bit - 온도 측정

OS/micro:bit 2018.02.23 21:02 Posted by 파란크리스마스

출처 : That IoT Thing: BBC micro:bit

#include "MicroBit.h" 

MicroBit uBit;

void temperatureUpdate(MicroBitEvent) {
	uBit.display.scroll( uBit.thermometer.getTemperature());
}

int main() { 
	uBit.init();
	uBit.display.scroll( uBit.thermometer.getTemperature());
	uBit.messageBus.listen(MICROBIT_ID_THERMOMETER, MICROBIT_THERMOMETER_EVT_UPDATE, temperatureUpdate);
}

Arduino Uno - ESP8266 ESP-01 Serial Wireless WIFI Module

OS/Arduino 2018.02.23 17:12 Posted by 파란크리스마스

출처 : GitHub - bportaluri/WiFiEsp: Arduino WiFi library for ESP8266 modules
GitHub - Diaoul/arduino-ESP8266: An Arduino library to manage the ESP8266.

WiFiEsp / ConnectWPA,ino

출처 : GitHub - bportaluri/WiFiEsp: Arduino WiFi library for ESP8266 modules

/*
 WiFiEsp example: ConnectWPA
 
 This example connects to an encrypted WiFi network using an ESP8266 module.
 Then it prints the  MAC address of the WiFi shield, the IP address obtained
 and other network details.

 For more details see: http://yaab-arduino.blogspot.com/p/wifiesp-example-connect.html
*/

#include "WiFiEsp.h"

// Emulate Serial1 on pins 6/7 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(6, 7); // RX, TX
#endif

char ssid[] = "Twim";            // your network SSID (name)
char pass[] = "12345678";        // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

void setup()
{
  // initialize serial for debugging
  Serial.begin(115200);
  // initialize serial for ESP module
  Serial1.begin(115200);
  // initialize ESP module
  WiFi.init(&Serial1);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  Serial.println("You're connected to the network");
}

void loop()
{
  // print the network connection information every 10 seconds
  Serial.println();
  printCurrentNet();
  printWifiData();
  
  delay(10000);
}

void printWifiData()
{
  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print your MAC address
  byte mac[6];
  WiFi.macAddress(mac);
  char buf[20];
  sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
  Serial.print("MAC address: ");
  Serial.println(buf);
}

void printCurrentNet()
{
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to
  byte bssid[6];
  WiFi.BSSID(bssid);
  char buf[20];
  sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", bssid[5], bssid[4], bssid[3], bssid[2], bssid[1], bssid[0]);
  Serial.print("BSSID: ");
  Serial.println(buf);

  // print the received signal strength
  long rssi = WiFi.RSSI();
  Serial.print("Signal strength (RSSI): ");
  Serial.println(rssi);
}

arduino-ESP8266 / Complete.ino

출처 : GitHub - Diaoul/arduino-ESP8266: An Arduino library to manage the ESP8266.

#include <SoftwareSerial.h>

#include "ESP8266.h"

SoftwareSerial esp8266Serial = SoftwareSerial(6, 7); // RX, TX
ESP8266 wifi = ESP8266(esp8266Serial);

void setup()
{
    Serial.begin(115200);

    // ESP8266
    esp8266Serial.begin(115200);
    wifi.begin();
    wifi.setTimeout(1000);

    /****************************************/
    /******       Basic commands       ******/
    /****************************************/
    // test
    /*Serial.print("test: ");
    Serial.println(getStatus(wifi.test()));*/

    // restart
    /*Serial.print("restart: ");
    Serial.println(getStatus(wifi.restart()));*/

    // getVersion
    char version[16] = {};
    Serial.print("getVersion: ");
    Serial.print(getStatus(wifi.getVersion(version, 16)));
    Serial.print(" : ");
    Serial.println(version);

    // deepSleep
    /*Serial.print("deepSleep: ");
    Serial.println(wifi.deepSleep(5000));*/

    // setBaudrate
    /*Serial.print("setBaudrate: ");
    Serial.println(wifi.setBaudrate(9600));*/

    /****************************************/
    /******        WiFi commands       ******/
    /****************************************/
    // setWifiMode
    Serial.print("setWifiMode: ");
    Serial.println(getStatus(wifi.setMode(ESP8266_WIFI_ACCESSPOINT)));

    // getWifiMode
    ESP8266WifiMode mode;
    Serial.print("getWifiMode: ");
    Serial.println(getStatus(wifi.getMode(&mode)));

    // joinAP
    /*Serial.print("joinAP: ");
    Serial.println(getStatus(wifi.joinAP("ssid", "password")));*/

    // getAP
    /*char ap[32] = {};
    Serial.print("getAP: ");
    Serial.print(getStatus(wifi.getAP(ap)));
    Serial.print(" : ");
    Serial.println(ap);*/

    // quitAP
    /*Serial.print("quitAP: ");
    Serial.println(getStatus(wifi.quitAP()));*/

    // setAPConfiguration
    Serial.print("setAPConfiguration: ");
    Serial.println(getStatus(wifi.setAPConfiguration("ESP8266", "awesomelib", 10, ESP8266_ENCRYPTION_WPA_WPA2_PSK)));
    wifi.restart();

    // getAPConfiguration
    char ssid[32] = {};
    char password[63] = {};
    uint8_t channel;
    ESP8266Encryption encryption;
    Serial.print("getAPConfiguration: ");
    Serial.print(getStatus(wifi.getAPConfiguration(ssid, password, channel, encryption)));
    Serial.print(" : ");
    Serial.print(ssid);
    Serial.print(" - ");
    Serial.print(password);
    Serial.print(" - ");
    Serial.print(channel);
    Serial.print(" - ");
    Serial.println(encryption);

    // setDHCP
    Serial.print("setDHCP STA: ");
    Serial.println(getStatus(wifi.setDHCP(ESP8266_WIFI_STATION, false)));
    Serial.print("setDHCP AP: ");
    Serial.println(getStatus(wifi.setDHCP(ESP8266_WIFI_ACCESSPOINT, true)));

    // setMAC
    /*byte mac[6] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11};
    Serial.print("setMAC AP: ");
    Serial.println(getStatus(wifi.setMAC(ESP8266_WIFI_ACCESSPOINT, mac)));*/

    // getMAC
    byte mac[6] = {};
    Serial.print("getMAC STA: ");
    Serial.print(getStatus(wifi.getMAC(ESP8266_WIFI_STATION, mac)));
    Serial.print(" : ");
    for (uint8_t i = 0; i < 6; i++) {
      Serial.print(mac[i], HEX);
      if (i < 5)
        Serial.print(":");
    }
    Serial.println();
    Serial.print("getMAC AP: ");
    Serial.print(getStatus(wifi.getMAC(ESP8266_WIFI_ACCESSPOINT, mac)));
    Serial.print(" : ");
    for (uint8_t i = 0; i < 6; i++) {
      Serial.print(mac[i], HEX);
      if (i < 5)
        Serial.print(":");
    }
    Serial.println();

    // setIP
    /*IPAddress ipAP = IPAddress(10, 0, 4, 1);
    Serial.print("setIP AP: ");
    Serial.print(getStatus(wifi.setIP(ESP8266_WIFI_ACCESSPOINT, ipAP)));
    Serial.print(" : ");
    Serial.println(ipAP);*/

    // getIP
    IPAddress ip;
    Serial.print("getIP STA: ");
    Serial.print(getStatus(wifi.getIP(ESP8266_WIFI_STATION, ip)));
    Serial.print(" : ");
    Serial.println(ip);
    Serial.print("getIP AP: ");
    Serial.print(getStatus(wifi.getIP(ESP8266_WIFI_ACCESSPOINT, ip)));
    Serial.print(" : ");
    Serial.println(ip);

    /****************************************/
    /******       TCP/IP commands      ******/
    /****************************************/
    // connect
    /*Serial.print("connect: ");
    Serial.println(getStatus(wifi.connect(ESP8266_PROTOCOL_TCP, IPAddress(192,168,4,100), 4000)));*/

    // send
    /*Serial.print("send: ");
    Serial.println(getStatus(wifi.send("Hello World\n")));*/

    // close
    /*Serial.print("close: ");
    Serial.println(getStatus(wifi.close()));*/

    // setMultipleConnections
    Serial.print("setMultipleConnections: ");
    Serial.println(getStatus(wifi.setMultipleConnections(true)));

    // getMultipleConnections
    /*bool multipleConnections;
    Serial.print("getMultipleConnections: ");
    Serial.print(getStatus(wifi.getMultipleConnections(multipleConnections)));
    Serial.print(" : ");
    Serial.println(multipleConnections);*/

    // createServer
    Serial.print("createServer: ");
    Serial.println(getStatus(wifi.createServer(4000)));

    // deleteServer
    Serial.print("deleteServer: ");
    Serial.println(getStatus(wifi.deleteServer()));

    // setServerTimeout
    /*Serial.print("setServerTimeout: ");
    Serial.println(getStatus(wifi.setServerTimeout(10)));*/

    // getServerTimeout
    /*unsigned int timeout;
    Serial.print("getServerTimeout: ");
    Serial.print(getStatus(wifi.getServerTimeout(timeout)));
    Serial.print(" : ");
    Serial.println(timeout);*/
}

void loop()
{
    /****************************************/
    /******        WiFi commands       ******/
    /****************************************/
    // getConnectedStations
    /*ESP8266Station stations[5];
    unsigned int stationCount;
    Serial.print("getConnectedStations: ");
    Serial.print(getStatus(wifi.getConnectedStations(stations, stationCount, 5)));
    Serial.print(" : ");
    Serial.println(stationCount);
    for (uint8_t i = 0; i < stationCount; i++) {
      Serial.print(" - ");
      Serial.print(stations[i].ip);
      Serial.print(" - ");
      for (uint8_t j = 0; j < 6; j++) {
        Serial.print(stations[i].mac[j], HEX);
        if (j < 5)
          Serial.print(":");
      }
      Serial.println();
    }
    delay(5000);*/

    /****************************************/
    /******       TCP/IP commands      ******/
    /****************************************/
    // getConnectionStatus
    /*ESP8266ConnectionStatus connectionStatus;
    ESP8266Connection connections[5];
    unsigned int connectionCount;
    Serial.print("getConnectionStatus: ");
    Serial.print(getStatus(wifi.getConnectionStatus(connectionStatus, connections, connectionCount)));
    Serial.print(" : ");
    Serial.println(connectionCount);
    for (int i = 0; i < connectionCount; i++) {
      Serial.print(" - Connection: ");
      Serial.print(connections[i].id);
      Serial.print(" - ");
      Serial.print(getProtocol(connections[i].protocol));
      Serial.print(" - ");
      Serial.print(connections[i].ip);
      Serial.print(":");
      Serial.print(connections[i].port);
      Serial.print(" - ");
      Serial.println(getRole(connections[i].role));
    }
    delay(5000);*/


    // read data
    /*unsigned int id;
    int length;
    int totalRead;
    char buffer[11] = {};

    if ((length = wifi.available()) > 0) {
      id = wifi.getId();
      totalRead = wifi.read(buffer, 10);

      if (length > 0) {
        Serial.print("Received ");
        Serial.print(totalRead);
        Serial.print("/");
        Serial.print(length);
        Serial.print(" bytes from client ");
        Serial.print(id);
        Serial.print(": ");
        Serial.println((char*)buffer);
      }
    }*/
}

String getStatus(bool status)
{
    if (status)
        return "OK";

    return "KO";
}

String getStatus(ESP8266CommandStatus status)
{
    switch (status) {
    case ESP8266_COMMAND_INVALID:
        return "INVALID";
        break;

    case ESP8266_COMMAND_TIMEOUT:
        return "TIMEOUT";
        break;

    case ESP8266_COMMAND_OK:
        return "OK";
        break;

    case ESP8266_COMMAND_NO_CHANGE:
        return "NO CHANGE";
        break;

    case ESP8266_COMMAND_ERROR:
        return "ERROR";
        break;

    case ESP8266_COMMAND_NO_LINK:
        return "NO LINK";
        break;

    case ESP8266_COMMAND_TOO_LONG:
        return "TOO LONG";
        break;

    case ESP8266_COMMAND_FAIL:
        return "FAIL";
        break;

    default:
        return "UNKNOWN COMMAND STATUS";
        break;
    }
}

String getRole(ESP8266Role role)
{
    switch (role) {
    case ESP8266_ROLE_CLIENT:
        return "CLIENT";
        break;

    case ESP8266_ROLE_SERVER:
        return "SERVER";
        break;

    default:
        return "UNKNOWN ROLE";
        break;
    }
}

String getProtocol(ESP8266Protocol protocol)
{
    switch (protocol) {
    case ESP8266_PROTOCOL_TCP:
        return "TCP";
        break;

    case ESP8266_PROTOCOL_UDP:
        return "UDP";
        break;

    default:
        return "UNKNOWN PROTOCOL";
        break;
    }
}

arduino-ESP8266 / HttpRequest.ino

출처 : GitHub - Diaoul/arduino-ESP8266: An Arduino library to manage the ESP8266.
Serial WiFi 모듈 (ESP8266) 활용편 | Hard Copy Arduino

#include <SoftwareSerial.h>

#include "ESP8266.h"

#define SSID "xxxxxxxx"
#define PASS "xxxxxxxx"
#define DST_IP "220.181.111.85" //baidu.com

SoftwareSerial esp8266Serial = SoftwareSerial(6, 7); // RX, TX
ESP8266 wifi = ESP8266(esp8266Serial);

void setup()
{
    Serial.begin(115200);

    // ESP8266
    esp8266Serial.begin(115200);
    wifi.begin();
    wifi.setTimeout(1000);

    /****************************************/
    /******       Basic commands       ******/
    /****************************************/
    // test
    Serial.print("test: ");
    Serial.println(getStatus(wifi.test()));

    // restart
    Serial.print("restart: ");
    Serial.println(getStatus(wifi.restart()));

    // getVersion
    char version[16] = {};
    Serial.print("getVersion: ");
    Serial.print(getStatus(wifi.getVersion(version, 16)));
    Serial.print(" : ");
    Serial.println(version);


    /****************************************/
    /******        WiFi commands       ******/
    /****************************************/
    // joinAP
    Serial.print("joinAP: ");
    Serial.println(getStatus(wifi.joinAP(SSID, PASS)));


    /****************************************/
    /******       TCP/IP commands      ******/
    /****************************************/
    // connect
    Serial.print("connect: ");
    Serial.println(getStatus(wifi.connect(ESP8266_PROTOCOL_TCP, DST_IP, 80)));

    // send
    Serial.print("send: ");
    Serial.println(getStatus(wifi.send("GET / HTTP/1.0\r\n\r\n")));

}

void loop()
{
    /****************************************/
    /******        WiFi commands       ******/
    /****************************************/

    // read data
    unsigned int id;
    int length;
    int totalRead;
    char buffer[300] = {};

    if ((length = wifi.available()) > 0) {
      id = wifi.getId();
      totalRead = wifi.read(buffer, 300);

      if (length > 0) {
        Serial.print("Received ");
        Serial.print(totalRead);
        Serial.print("/");
        Serial.print(length);
        Serial.print(" bytes from client ");
        //Serial.print("from client ");
        Serial.print(id);
        Serial.print(": ");
        Serial.println((char*)buffer);
      }
    }
}

String getStatus(bool status)
{
    if (status)
        return "OK";

    return "KO";
}

micro:bit - Elecfreaks Joystick:bit

OS/micro:bit 2018.02.15 20:19 Posted by 파란크리스마스

출처 : Arduino Space Invaders Part 8 - Scoring
ELECFREAKS Joystick:bit for Micro:bit - ElecFreaks
https://makecode.microbit.org/_M9eHWe0aMc1D

micro:bit - Elecfreaks Joystick:bit

   

JavaScript 소스

C++ 소스

#include "MicroBit.h"

MicroBit uBit;

// P10 = P0_6 - joystick down
AnalogIn joystick_button(P0_1);
AnalogIn joystick_y(P0_2);
AnalogIn joystick_x(P0_3);


int main()
{
  // Initialise the micro:bit runtime.
  uBit.init();
  uBit.display.scroll("joystick");

  while(1) { 
  	if (joystick_button.read() < 0.256) {
 		uBit.display.scroll("1");
 	} else if (joystick_button.read() < 0.597) {
 		uBit.display.scroll("2");
 	} else if (joystick_button.read() < 0.725) {
 		uBit.display.scroll("3");
 	} else if (joystick_button.read() < 0.793) {
 		uBit.display.scroll("4");
 	} else if (joystick_button.read() < 0.836) {
 		uBit.display.scroll("5");
 	} else if (joystick_button.read() < 0.938) {
 		uBit.display.scroll("6");
	} else if (joystick_x.read() < 0.4) {
 		uBit.display.scroll("-X");
 	} else if (joystick_x.read() > 0.6) {
 		uBit.display.scroll("+X");
 	} else if (joystick_y.read() < 0.4) {
 		uBit.display.scroll("-Y");
 	} else if (joystick_y.read() > 0.6) {
 		uBit.display.scroll("+Y");
 	} else {
 		uBit.display.clear();
 	}
 	wait(1.0 );
  }
}

활용 - Space invaders (Using Joystick:bit)

pulse-combined.hex

micro:bit - BLE - RC Car -PWM 사용

OS/micro:bit 2018.02.03 00:27 Posted by 파란크리스마스

본 체험 제품은 element14 의 후원을 받아 아이씨뱅큐㈜ 에서 진행하는 무상 체험단 활동으로 작성한 것입니다.

출처 : Motor Driver Board for the BBC micro:bit - V2 | Kitronik
Blog Yamasho: Delphi 10.2.2:Bleで Microbitと通信する。
googlesamples/android-BluetoothLeGatt - GitHub
ButtonService - micro:bit runtime
microbit-samples/source/examples/bluetooth-services/main.cpp - GitHub
https://github.com/lancaster-university/microbit-dal/issues/337
Advanced - micro:bit runtime - GitHub Pages
Send/Receive Data Using BLE and MBED | BBC:Microbit - Instructables

micro:bit - BLE - RC Car -PWM 사용

main.cpp

MicroBitRCCAR.apk.zip

pulse-combined.hex

micro:bit 확장 보드중에 모터 드라이버(Motor Driver Board for the BBC micro:bit - V2 | Kitronik)를 이용해서 RC Car를 만들어 보았습니다. 통신방식은 micro:bit에 내장된 BLE를 이용했고, 클라이언트는 Delphi를 이용해서 만들어 보았습니다. 제가 사용한 모터 드라이버는 RWM를 사용해서 속도 제어도 가능했습니다.

 

 

소스 - main.cpp

#include "MicroBit.h" 
#include "MicroBitUARTService.h"

MicroBit uBit;
MicroBitUARTService *uart;

#define MOTER_LOW            0
#define MOTER_HIGH           0.2 // 스피드 - 0 ~ 1 | 최대속도 = 1

PwmOut moter_right_front(P0_18);	//12 - right
PwmOut moter_right_back(P0_20);		//8
PwmOut moter_left_front(P0_3);		//16 - left
PwmOut moter_left_back(P0_16);			//0

//모터A,B 정회전
void bothMotorStart()
{
  moter_right_front = MOTER_HIGH;
  moter_right_back = MOTER_LOW;
  moter_left_front = MOTER_HIGH;
  moter_left_back = MOTER_LOW;
}
 
//모터A,B 역회전
void bothMotorBack()
{
  moter_right_front = MOTER_LOW;
  moter_right_back = MOTER_HIGH;
  moter_left_front = MOTER_LOW;
  moter_left_back = MOTER_HIGH;
}
   
//모터A,B Stop
void stopAllMotor()
{
  moter_right_front = MOTER_LOW;
  moter_right_back = MOTER_LOW;
  moter_left_front = MOTER_LOW;
  moter_left_back = MOTER_LOW;
}
   
//모터A 역회전, 모터B 정회전
void turnLeft()
{
  moter_right_front = MOTER_LOW;
  moter_right_back = MOTER_HIGH;
  moter_left_front = MOTER_HIGH;
  moter_left_back = MOTER_LOW;
}
   
//모터A 정회전, 모터B 역회전
void turnRight()
{
  moter_right_front = MOTER_HIGH;
  moter_right_back = MOTER_LOW;
  moter_left_front = MOTER_LOW;
  moter_left_back = MOTER_HIGH;
}
   
//모터A 정회전, 모터B Stop
void motorA_Rotation()
{
  moter_right_front = MOTER_HIGH;
  moter_right_back = MOTER_LOW;
  moter_left_front = MOTER_LOW;
  moter_left_back = MOTER_LOW;
}
   
//모터A Stop, 모터B 정회전
void motorB_Rotation()
{
  moter_right_front = MOTER_LOW;
  moter_right_back = MOTER_LOW;
  moter_left_front = MOTER_HIGH;
  moter_left_back = MOTER_LOW;
}
   
//모터A 역회전, 모터B Stop
void motorA_Reverse()
{
  moter_right_front = MOTER_LOW;
  moter_right_back = MOTER_HIGH;
  moter_left_front = MOTER_LOW;
  moter_left_back = MOTER_LOW;
}
   
//모터A Stop, 모터B 역회전
void motorB_Reverse()
{
  moter_right_front = MOTER_LOW;
  moter_right_back = MOTER_LOW;
  moter_left_front = MOTER_LOW;
  moter_left_back = MOTER_HIGH;
}

// we use events abd the 'connected' variable to keep track of the status of the Bluetooth connection
void onConnected(MicroBitEvent)
{
    uBit.display.print("C");

    while(1) {
      char command = uart->getc();
      uBit.display.print(command);
      
      if (command == 'F') {
      	bothMotorStart();
      } else if (command == 'B') {
      	bothMotorBack();
      } else if (command == 'L') {
      	turnLeft();
      } else if (command == 'R') {
      	turnRight();
      } else if (command == 'S') {
      	stopAllMotor();
      }
    }
}
 
void onDisconnected(MicroBitEvent)
{
    uBit.display.print("D");
}

int main() { 
  uBit.init();
  uBit.display.scroll("MOTER");
  
  /*  
  while(1) {
    bothMotorStart();
    wait(1);
    stopAllMotor();
    wait(1);
    bothMotorBack();
    wait(1);
    stopAllMotor();
    wait(1);
  }
  */
	
  uBit.messageBus.listen(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_CONNECTED, onConnected);
  uBit.messageBus.listen(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_DISCONNECTED, onDisconnected);
	
  uart = new MicroBitUARTService(*uBit.ble, 32, 32); 
  uBit.display.scroll("UART ready");

  release_fiber();   
}

실행

마이크로비트 공식 구입처 : 아이씨뱅큐 http://www.icbanq.com/
엘리먼트14의 특장점 - 글로벌 전자부품 유통회사, 6만원 이상 무료배송, 60만가지 재고 보유, MOQ 없음, 한글 웹사이트, 국내서비스센터 운영 (http://kr.element14.com/?CMP=DSP-ODB-KR-JAN2018-BLOG-ICBanQ1-HOMEPAGE)

마이크로비트 공식 카페 : http://cafe.naver.com/bbcmicro
아이씨뱅큐 공식 블로그 : http://blog.naver.com/icbanq



 

티스토리 툴바