1080P Pinebook - PINE64

OS/1080P Pinebook 2019.02.24 21:55 Posted by 파란크리스마스

출처

SD 확장

SD 확장전 용량확인

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       5.7G  5.4G  377M  94% /
devtmpfs        739M     0  739M   0% /dev
tmpfs           995M     0  995M   0% /dev/shm
tmpfs           995M  1.1M  994M   1% /run
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           995M     0  995M   0% /sys/fs/cgroup
tmpfs           199M   12K  199M   1% /run/user/1000

SD FDisk

live@live-pc:~$ sudo fdisk /dev/mmcblk0

Welcome to fdisk (util-linux 2.31.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): p
Disk /dev/mmcblk0: 29.7 GiB, 31914983424 bytes, 62333952 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x99dd6e95

Device         Boot Start      End  Sectors  Size Id Type
/dev/mmcblk0p1 *    40960 12287999 12247040  5.9G 83 Linux

Command (m for help): d
Selected partition 1
Partition 1 has been deleted.

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-62333951, default 2048): 40960
Last sector, +sectors or +size{K,M,G,T,P} (40960-62333951, default 62333951): 

Created a new partition 1 of type 'Linux' and of size 29.7 GiB.
Partition #1 contains a ext4 signature.

Do you want to remove the signature? [Y]es/[N]o: Y

The signature will be removed by a write command.

Command (m for help): w
The partition table has been altered.
Syncing disks.

live@live-pc:~$ sudo shutdown -r now

SD 확장

$ sudo resize2fs /dev/mmcblk0p1
resize2fs 1.44.1 (24-Mar-2018)
Filesystem at /dev/mmcblk0p1 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 2
The filesystem on /dev/mmcblk0p1 is now 7786624 (4k) blocks long.

SD 확장 확인

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        30G  5.4G   24G  19% /
devtmpfs        739M     0  739M   0% /dev
tmpfs           995M   11M  985M   2% /dev/shm
tmpfs           995M  1.1M  994M   1% /run
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           995M     0  995M   0% /sys/fs/cgroup
tmpfs           199M   12K  199M   1% /run/user/1000

eMMC에 OS 설치

$ sudo dd if=neon-pinebook-remix-useredition-20190217-1500-arm64-1080p.img of=/dev/mmcblk1 bs=4MB status=progress conv=sync
6284000000 bytes (6.3 GB, 5.9 GiB) copied, 320 s, 19.6 MB/s
1572+1 records in
1573+0 records out
6292000000 bytes (6.3 GB, 5.9 GiB) copied, 324.49 s, 19.4 MB/s

원격 데스크톱 - Krfb (VNC protocol)

Krfb 설치

$ sudo apt-get install krfb
[sudo] password for live: 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  libvncserver1
The following NEW packages will be installed:
  krfb libvncserver1
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,074 kB of archives.
After this operation, 2,404 kB of additional disk space will be used.

K Menu (Kickoff) -> Applications -> Internet -> Desktop Sharing (Krfb)

원격 데스크톱 - NoMachine

NoMachine 설치

$ sudo dpkg -i nomachine_6.5.6_7_arm64.deb
Selecting previously unselected package nomachine.
(Reading database ... 152723 files and directories currently installed.)
Preparing to unpack nomachine_6.5.6_7_arm64.deb ...
Unpacking nomachine (6.5.6-7) ...
Setting up nomachine (6.5.6-7) ...
NX> 700 Starting install at: Tue Feb 26 22:24:01 2019.
NX> 700 Installing: nxclient version: 6.5.6.
NX> 700 Using installation profile: Debian.
NX> 700 Install log is: /usr/NX/var/log/nxinstall.log.
NX> 700 Compiling the USB module.
NX> 700 Installing: nxplayer version: 6.5.6.
NX> 700 Using installation profile: Debian.
NX> 700 Install log is: /usr/NX/var/log/nxinstall.log.
NX> 700 To connect the remote printer to the local desktop,
NX> 700 the user account must be a member of the CUPS System Group: lpadmin.
NX> 700 Installing: nxnode version: 6.5.6.
NX> 700 Using installation profile: Debian.
NX> 700 Install log is: /usr/NX/var/log/nxinstall.log.
NX> 700 Creating configuration in: /usr/NX/etc/node.cfg.
NX> 700 Installing: nxserver version: 6.5.6.
NX> 700 Using installation profile: Debian.
NX> 700 Install log is: /usr/NX/var/log/nxinstall.log.
NX> 700 Creating configuration in: /usr/NX/etc/server.cfg.
NX> 700 Install completed at: Tue Feb 26 02:24:58 2019.
NX> 700 NoMachine was configured to run the following services:
NX> 700 NX service on port: 4000

포트 확인

$ nmap localhost
 
Starting Nmap 7.60 ( https://nmap.org ) at 2019-02-26 02:38 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00059s latency).
Other addresses for localhost (not scanned): ::1
Not shown: 994 closed ports
PORT      STATE SERVICE
22/tcp    open  ssh
631/tcp   open  ipp
3389/tcp  open  ms-wbt-server
4000/tcp  open  remoteanything
7001/tcp  open  afs3-callback
20000/tcp open  dnp

한글 입력기 설치 (fcitx)

출처 : Localization/Korean (한국어) - ArchWiki

fcitx-hangul 설치

$ sudo apt-get install fcitx-hangul fcitx-frontend-qt4 im-config

한글 입력기 부팅시 시작하기

$ im-config -n fcitx

한글 입력기 설정 확인

$ cat ~/.xinputrc
## im-config(8) generated on Tue, 05 Mar 2019 23:19:59 +0900
run_im fcitx
## im-config signature: 962aab32bb5f1fff611ee7ed31737694  -

fcitx 설정

$ vi ~/.xinputrc

export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx

M5Stack Korea인 WIZnet에서 운영하는 메이커 컨텐츠 커뮤니티 사이트의 후원을 받아서 작성되었습니다.

출처

M5Go Port

PORT A : GPIO 21, 22 pin / I2C 통신
PORT B : GPIO 26, 36 pin
PORT C : GPIO 16, 17 pin

M5Stack : 온도센서 (ENV Unit with DHT12 BMP280 Digital DHT-12 Temperature Humidity Aire Pressure Sensor)

M5GO에 포함 된 온도 센서는 DHT12과 BMP280가 들어가있어 각각 온도와 습도, 온도와 기압을 측정 할 수 있습니다.

M5Go의 A Port와 ENV Unit을 Grove 케이블로 연결하고, DHT12 객체만 사용하면 A Port가 바로 I2C 통신하므로 핀 설정 없이 사용할 수 있습니다.

아두이노 소스

#include <M5Stack.h>
#include "DHT12.h"
#include <Wire.h>     //The DHT12 uses I2C comunication.
DHT12 dht12;          //Preset scale CELSIUS and ID 0x5c.

void setup() {
  M5.begin();
  M5.Lcd.setTextSize(2);
  Wire.begin();
  Serial.println("Prueba de libreria DHT12:");
  M5.Lcd.println("Prueba de libreria DHT12:");
}

void loop() {
  //Read temperature with preset scale.
  Serial.print("Temperatura: ");
  M5.Lcd.print("Temperatura: ");
  Serial.print(dht12.readTemperature());
  M5.Lcd.print(dht12.readTemperature());

  //Read humidity.
  Serial.print("*C  Humedad: ");
  M5.Lcd.print("*C  Humedad: ");
  Serial.print(dht12.readHumidity());
  M5.Lcd.println(dht12.readHumidity());

  //Read temperature as forced fahrenheit.
  Serial.println("%RH");
  Serial.println("%RH");
  Serial.print("Temperatura: ");
  Serial.print(dht12.readTemperature(FAHRENHEIT));

  //Read termperature as forced kelvin.
  Serial.println("*F");
  Serial.print("Temperatura: ");
  Serial.print(dht12.readTemperature(KELVIN));
  Serial.println("*K");

  delay(5000);
}

M5Stack : RGB Unit with NeoPixel RGB LED Light x3

OS/M5Stack 2019.02.24 14:04 Posted by 파란크리스마스

M5Stack Korea인 WIZnet에서 운영하는 메이커 컨텐츠 커뮤니티 사이트의 후원을 받아서 작성되었습니다.

출처

M5Go Port

PORT A : GPIO 21, 22 pin
PORT B : GPIO 26, 36 pin
PORT C : GPIO 16, 17 pin

M5Stack : RGB Unit with NeoPixel RGB LED Light x3

RGB Unit은 3 개의 RGB LED 조명과 2 개의 GROVE 포트를 포함하는 센서입니다. Blockly, Arduino 또는 MicroPython을 통해 M5GO Core를 사용하여 지정된 색상을 표시 할 수 있습니다.

M5Go의 B Port와 RGB Unit을 Grove 케이블로 연결하고, Adafruit_NeoPixel 라이브러리를 사용하시면 됩니다.

아두이노 전체 소스

/*
    Install the AdaFruit NeoPixel library first
 */
#include <Adafruit_NeoPixel.h>
 
#define RGB_PIN 26
#define NUMPIXELS   3
 
// new a object
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, RGB_PIN, NEO_GRB+NEO_KHZ800);

int delayval = 150; // delay for half a second

void setup() {
  pixels.begin(); // This initializes the NeoPixel library.
}

void loop() {
  pixels.setPixelColor(0, pixels.Color(100,0,0)); // Moderately bright red color.
  pixels.setPixelColor(1, pixels.Color(0,100,0)); // Moderately bright green color.
  pixels.setPixelColor(2, pixels.Color(0,0,100)); // Moderately bright blue color.

  pixels.show(); // This sends the updated pixel color to the hardware.
  delay(delayval); // Delay for a period of time (in milliseconds)

  pixels.setPixelColor(0, pixels.Color(0,100,0));
  pixels.setPixelColor(1, pixels.Color(0,0,100));
  pixels.setPixelColor(2, pixels.Color(100,0,0));
  pixels.show();
  delay(delayval);

  pixels.setPixelColor(0, pixels.Color(0,0,100));
  pixels.setPixelColor(1, pixels.Color(100,0,0));
  pixels.setPixelColor(2, pixels.Color(0,100,0));
  pixels.show();
  delay(delayval);

  // pixels.setPixelColor(0, pixels.Color(100,100,100));
  // pixels.setPixelColor(1, pixels.Color(100,100,100));
  // pixels.setPixelColor(2, pixels.Color(100,100,100));
  // pixels.show();
  // delay(delayval);
}

실행결과

M5Stack Korea인 WIZnet에서 운영하는 메이커 컨텐츠 커뮤니티 사이트의 후원을 받아서 작성되었습니다.

출처

M5Stack : 적외선 인체감지 센서 모듈 - 디지탈값 가져오기

PIR 센서는 사람의 몸에서 나오는 적외선을 감지 할 수있는 장치입니다. 누군가 움직을 감지 할 수 있습니다. 

PIR 센서는 적외선의 변경된 것을 감지하면 PIR의 신호 핀이 하이 레벨을 출력합니다. 그렇지 않으면 로우 레벨로 출력됩니다.

M5Go의 B Port와 적외선 센서을 Grove 케이블로 연결하고, M5Go의 B Port는 36번핀으로 디지탈 input 초기화( pinMode(36, INPUT); )를 setup 함수에서 하고, loop 함수에서 디지탈 값을 측정하는 함수( digitalRead(36); )를 사용 하시면 됩니다.

아두이노 핀 초기화

#define sensorPin 36
void setup() {
  pinMode(sensorPin, INPUT);
}

디지탈 값을 축정

void loop() {
  int cur_sensorValue = digitalRead(sensorPin);
}

아두이노 전체 소스

#include <M5Stack.h>

// The scrolling area must be a integral multiple of TEXT_HEIGHT
#define TEXT_HEIGHT 23 // Height of text to be printed and scrolled
#define BOT_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen)
#define TOP_FIXED_AREA 0 // Number of lines in top fixed area (lines counted from top of screen)
#define YMAX 230 // Bottom of screen area

// The initial y coordinate of the top of the scrolling area
uint16_t yStart = TOP_FIXED_AREA;
// yArea must be a integral multiple of TEXT_HEIGHT
uint16_t yArea = YMAX-TOP_FIXED_AREA-BOT_FIXED_AREA;
// The initial y coordinate of the top of the bottom text line
uint16_t yDraw = YMAX - BOT_FIXED_AREA - TEXT_HEIGHT;

// Keep track of the drawing x coordinate
uint16_t xPos = 0;

// For the byte we read from the serial port
byte data = 0;

// A few test variables used during debugging
boolean change_colour = 1;
boolean selected = 1;

// We have to blank the top line each time the display is scrolled, but this takes up to 13 milliseconds
// for a full width line, meanwhile the serial buffer may be filling... and overflowing
// We can speed up scrolling of short text lines by just blanking the character we drew
int blank[19]; // We keep all the strings pixel lengths to optimise the speed of the top line blanking

// select the input pin for the potentiometer
#define sensorPin 36
 
// declaration
int cur_sensorValue = 0;

void setup() {
  M5.begin();
  M5.Lcd.fillScreen(TFT_BLACK);

  // Change colour for scrolling zone text
  M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);

  // Setup scroll area
  setupScrollArea(TOP_FIXED_AREA, BOT_FIXED_AREA);

  //
  pinMode(sensorPin, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  cur_sensorValue = digitalRead(sensorPin);
  char str[256];
  sprintf(str, "PIR sensor value = %d\n", cur_sensorValue);
  Serial.println(str);
  drawCentreString(str);    
  delay(100);
}

void drawCentreString(String message) {
    byte data[message.length()];
    message.getBytes(data, message.length());

    for (int i = 0; i < message.length(); i++ ) {
        byte data = message[i];
        
        // If it is a CR or we are near end of line then scroll one line
        if (data == '\r' || xPos>321) {
          // 새줄
          xPos = 0;
          yDraw = scroll_line(); // It can take 13ms to scroll and blank 16 pixel lines
        }
        if (data > 31 && data < 128) {
          xPos += M5.Lcd.drawChar(data,xPos,yDraw,4);
          blank[(18+(yStart-TOP_FIXED_AREA)/TEXT_HEIGHT)%19]=xPos; // Keep a record of line lengths
        }
        //change_colour = 1; // Line to indicate buffer is being emptied
    }

    // 새줄
    xPos = 0;
    yDraw = scroll_line(); // It can take 13ms to scroll and blank 16 pixel lines
}

// ##############################################################################################
// Call this function to scroll the display one text line
// ##############################################################################################
int scroll_line() {
  int yTemp = yStart; // Store the old yStart, this is where we draw the next line
  // Use the record of line lengths to optimise the rectangle size we need to erase the top line
  // M5.Lcd.fillRect(0,yStart,blank[(yStart-TOP_FIXED_AREA)/TEXT_HEIGHT],TEXT_HEIGHT, TFT_BLACK);

  // LCD 초기화 
  if (yStart == 0)
    M5.Lcd.fillScreen(TFT_BLACK);

  // Change the top of the scroll area
  yStart+=TEXT_HEIGHT;
  // The value must wrap around as the screen memory is a circular buffer
  if (yStart >= YMAX - BOT_FIXED_AREA) 
    yStart = TOP_FIXED_AREA + (yStart - YMAX + BOT_FIXED_AREA);
    
  // Now we can scroll the display
  scrollAddress(yStart);
  
  return  yTemp;
}

// ##############################################################################################
// Setup a portion of the screen for vertical scrolling
// ##############################################################################################
// We are using a hardware feature of the display, so we can only scroll in portrait orientation
void setupScrollArea(uint16_t tfa, uint16_t bfa) {
  M5.Lcd.writecommand(ILI9341_VSCRDEF); // Vertical scroll definition
  M5.Lcd.writedata(tfa >> 8);           // Top Fixed Area line count
  M5.Lcd.writedata(tfa);
  M5.Lcd.writedata((YMAX-tfa-bfa)>>8);  // Vertical Scrolling Area line count
  M5.Lcd.writedata(YMAX-tfa-bfa);
  M5.Lcd.writedata(bfa >> 8);           // Bottom Fixed Area line count
  M5.Lcd.writedata(bfa);
}

// ##############################################################################################
// Setup the vertical scrolling start address pointer
// ##############################################################################################
void scrollAddress(uint16_t vsp) {
  M5.Lcd.writecommand(ILI9341_VSCRSADD); // Vertical scrolling pointer
  M5.Lcd.writedata(vsp>>8);
  M5.Lcd.writedata(vsp);
}

실행결과

M5Stack : 가변저항(아날로그) 값 가져오기

OS/M5Stack 2019.02.20 01:05 Posted by 파란크리스마스

M5Stack Korea인 WIZnet에서 운영하는 메이커 컨텐츠 커뮤니티 사이트의 후원을 받아서 작성되었습니다.

출처

M5Stack : 가변저항(아날로그) 값 가져오기

M5Stack에서도 아날로그 값을 측정 할 수 있는데, M5Stack Iot Starter Kit의 가변저항(아날로그) 값을 축정하는 함수(analogRead)로 아날로그 결과 값을 받아 와서 LCD에 출력 해보았습니다.

M5Go의 B Port와 가변저항을 Grove 케이블로 연결하고, M5Go의 B Port는 36번핀으로 아날로그 input 초기화( pinMode(36, INPUT); )를 setup 함수에서 하고, loop 함수에서 아날로그 값을 측정하는 함수( analogRead(36); )를 사용 하시면 됩니다.

아두이노 핀 초기화

#define sensorPin 36
void setup() {
  pinMode(sensorPin, INPUT);
}

아날로그 값을 축정

void loop() {
  int cur_sensorValue = analogRead(sensorPin);
}

아두이노 전체 소스

#include <M5Stack.h>

// The scrolling area must be a integral multiple of TEXT_HEIGHT
#define TEXT_HEIGHT 23 // Height of text to be printed and scrolled
#define BOT_FIXED_AREA 0 // Number of lines in bottom fixed area (lines counted from bottom of screen)
#define TOP_FIXED_AREA 0 // Number of lines in top fixed area (lines counted from top of screen)
#define YMAX 230 // Bottom of screen area

// The initial y coordinate of the top of the scrolling area
uint16_t yStart = TOP_FIXED_AREA;
// yArea must be a integral multiple of TEXT_HEIGHT
uint16_t yArea = YMAX-TOP_FIXED_AREA-BOT_FIXED_AREA;
// The initial y coordinate of the top of the bottom text line
uint16_t yDraw = YMAX - BOT_FIXED_AREA - TEXT_HEIGHT;

// Keep track of the drawing x coordinate
uint16_t xPos = 0;

// For the byte we read from the serial port
byte data = 0;

// A few test variables used during debugging
boolean change_colour = 1;
boolean selected = 1;

// We have to blank the top line each time the display is scrolled, but this takes up to 13 milliseconds
// for a full width line, meanwhile the serial buffer may be filling... and overflowing
// We can speed up scrolling of short text lines by just blanking the character we drew
int blank[19]; // We keep all the strings pixel lengths to optimise the speed of the top line blanking

// select the input pin for the potentiometer
#define sensorPin 36
 
// declaration
int cur_sensorValue = 0;

void setup() {
  M5.begin();
  M5.Lcd.fillScreen(TFT_BLACK);

  // Change colour for scrolling zone text
  M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);

  // Setup scroll area
  setupScrollArea(TOP_FIXED_AREA, BOT_FIXED_AREA);

  //
  pinMode(sensorPin, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  cur_sensorValue = analogRead(sensorPin);
  char str[256];
  sprintf(str, "potentiometer value = %d\n", cur_sensorValue);
  Serial.println(str);
  drawCentreString(str);    
  delay(100);
}

void drawCentreString(String message) {
    byte data[message.length()];
    message.getBytes(data, message.length());

    for (int i = 0; i < message.length(); i++ ) {
        byte data = message[i];
        
        // If it is a CR or we are near end of line then scroll one line
        if (data == '\r' || xPos>321) {
          // 새줄
          xPos = 0;
          yDraw = scroll_line(); // It can take 13ms to scroll and blank 16 pixel lines
        }
        if (data > 31 && data < 128) {
          xPos += M5.Lcd.drawChar(data,xPos,yDraw,4);
          blank[(18+(yStart-TOP_FIXED_AREA)/TEXT_HEIGHT)%19]=xPos; // Keep a record of line lengths
        }
        //change_colour = 1; // Line to indicate buffer is being emptied
    }

    // 새줄
    xPos = 0;
    yDraw = scroll_line(); // It can take 13ms to scroll and blank 16 pixel lines
}

// ##############################################################################################
// Call this function to scroll the display one text line
// ##############################################################################################
int scroll_line() {
  int yTemp = yStart; // Store the old yStart, this is where we draw the next line
  // Use the record of line lengths to optimise the rectangle size we need to erase the top line
  // M5.Lcd.fillRect(0,yStart,blank[(yStart-TOP_FIXED_AREA)/TEXT_HEIGHT],TEXT_HEIGHT, TFT_BLACK);

  // LCD 초기화 
  if (yStart == 0)
    M5.Lcd.fillScreen(TFT_BLACK);

  // Change the top of the scroll area
  yStart+=TEXT_HEIGHT;
  // The value must wrap around as the screen memory is a circular buffer
  if (yStart >= YMAX - BOT_FIXED_AREA) 
    yStart = TOP_FIXED_AREA + (yStart - YMAX + BOT_FIXED_AREA);
    
  // Now we can scroll the display
  scrollAddress(yStart);
  
  return  yTemp;
}

// ##############################################################################################
// Setup a portion of the screen for vertical scrolling
// ##############################################################################################
// We are using a hardware feature of the display, so we can only scroll in portrait orientation
void setupScrollArea(uint16_t tfa, uint16_t bfa) {
  M5.Lcd.writecommand(ILI9341_VSCRDEF); // Vertical scroll definition
  M5.Lcd.writedata(tfa >> 8);           // Top Fixed Area line count
  M5.Lcd.writedata(tfa);
  M5.Lcd.writedata((YMAX-tfa-bfa)>>8);  // Vertical Scrolling Area line count
  M5.Lcd.writedata(YMAX-tfa-bfa);
  M5.Lcd.writedata(bfa >> 8);           // Bottom Fixed Area line count
  M5.Lcd.writedata(bfa);
}

// ##############################################################################################
// Setup the vertical scrolling start address pointer
// ##############################################################################################
void scrollAddress(uint16_t vsp) {
  M5.Lcd.writecommand(ILI9341_VSCRSADD); // Vertical scrolling pointer
  M5.Lcd.writedata(vsp>>8);
  M5.Lcd.writedata(vsp);
}

실행결과

M5Stack : M5CAMERA

OS/M5Stack 2019.02.19 23:01 Posted by 파란크리스마스

M5Stack Korea인 WIZnet에서 운영하는 메이커 컨텐츠 커뮤니티 사이트의 후원을 받아서 작성되었습니다.

출처

M5Stack : M5CAMERA

M5CAMERA는 와이파이 AP모드로 PC나 스마트폰에서 와이파이로 접속하게되면 M5CAMERA로 부터 아이피를 부여받게 되고, 와이파이에 접속한 PC나 스마트폰의 브라우져를 통해서 http://192.168.4.1에 접속하면 M5CAMERA로 촬영한 영상을 얻을 수 있습니다.

M5CAMERA는 M5Stack과 마찬가지로 ESP32칩으로 만들어져서 아두이노나 MicroPython언어로 개발이 가능합니다.

M5CAMERA의 펌웨어를 최신 버전으로 적용해야 MicroPython의 최신 함수도 지원하고, 기능도 개선되므로 최신버전의 펌웨어 적용을 권장합니다.

펌웨어를 적용하면 와이파이 SSID가 변경이 될 수도 있는데, 최신버전으로 업그레이드 하게되면 SSID가 M5Psram_Cam으로 변경되었습니다.

단점이 있다면 하나의 기기만 접속을 허용하고 있어서 이미 접속이 되어 있는 경우 다른 기기는 접속을 허용하지 않습니다.

M5CAMERA의 동영상 스트리밍 방식은 mjpg streamer 방식으로 jpg 이미지를 연속으로 http 웹서비스 하는 방식으로 일반적으로 현관문 CCTV에 많이 사용하는 방식중에 하나 입니다.

  

  

  

스마트폰에서 M5CAMERA의 영상 받아보기

스마트폰에서 M5CAMERA의 접속

스마트폰의 와이파이 목록에서 M5Cam-xxxx (펌웨어의 버전에 따라서 이름이 변경되고 있음)을 찾아서 와이파이 연결하고, 연결이 되면 스마트폰 브라우져에서 192.168.4.1로 접속하면 M5CAMERA의 영상이 보입니다.

    

M5CAMERA의 로그

브라우져로 영상 받아오기

M5Stack에서 M5CAMERA 영상 받아오기

예제 소스에는 M5CAMERA의 영상을 받아 와서 M5Stack LCD에 보여 주고 있지만, 지금 가지고 있는 M5Stack 모델은 메모리가 부족 해서 소스를 수정해서 일부만 LCD에 보여주고 있습니다. 다음에 기회가 된다면 M5Stack 4M-PSRAM모델에서 전체 영상을 받아서 보여주는 예제를 실행해보겠습니다.

수정한 아두이노 소스

#define SSID_NAME "M5Psram_Cam"
#define SSID_PASSWORD ""
#define URL "http://192.168.4.1/jpg"
#define BUFFER_MAX 1024 * 6   // 최대 메모리 크기 설정

#include <M5Stack.h>
#include <WiFi.h>
#include <HTTPClient.h>

void setup() {
  M5.begin();
  M5.Lcd.setBrightness(255);
  WiFi.begin(SSID_NAME, SSID_PASSWORD);
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    // wait for WiFi connection
    delay(1000);
  } else {
    HTTPClient http;

    Serial.print("[HTTP] begin...\n");
    http.begin(URL);

    Serial.print("[HTTP] GET...\n");
    int httpCode = http.GET();

    Serial.printf("[HTTP] GET... code: %d\n", httpCode);
    // HTTP header has been send and Server response header has been handled
    if (httpCode <= 0) {
      Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    } else {
      if (httpCode != HTTP_CODE_OK) {
        Serial.printf("[HTTP] Not OK!\n");
      } else {
        // get lenght of document (is -1 when Server sends no Content-Length header)
        int len = http.getSize();
        Serial.printf("[HTTP] size: %d\n", len);

        if (len <= 0) {
          Serial.printf("[HTTP] Unknow content size: %d\n", len);
        } else {
          // 버퍼크기 설정 - M5Stack의 메모리 한계로 최대 메모리 설정(BUFFER_MAX ) 만큼 버퍼 크기 설정
          int buffer_len = len > BUFFER_MAX ? BUFFER_MAX : len;
          
          // create buffer for read
          uint8_t buff[buffer_len] = { 0 };

          // get tcp stream
          WiFiClient * stream = http.getStreamPtr();

          // read all data from server
          uint8_t* p = buff;
          int l = 0;
          while (http.connected() && (l < sizeof(buff)) /*(l == 0 || len == -1)*/) {
            // get available data size
            size_t size = stream->available();

            if (size) {
              int s = ((size + l > sizeof(buff)) ? sizeof(buff) - l : size);
              int c = stream->readBytes(p, s);
              p += c;

              Serial.printf("[HTTP] read: %d\n", c);
              l += c;
            }
          }

          Serial.println();
          Serial.print("[HTTP] connection closed.\n");
          
          M5.Lcd.drawJpg(buff, sizeof(buff));

          // LCD display
          M5.Lcd.drawString("http://bluexmas.tistory.com", M5.Lcd.width() - 170, M5.Lcd.height() - 20, 2);
        }
      }
    }

    http.end();
  }
}

실행

  

원본 소스를 사용했을 경우 메모리가 부족해서 발생하는 오류 메시지

ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1100
load:0x40078000,len:10088
load:0x40080400,len:6380
entry 0x400806a4
M5Stack initializing...OK
[HTTP] begin...
[HTTP] GET...
[HTTP] GET... code: 200
[HTTP] size: 17937
Guru Meditation Error: Core  1 panic'ed (Unhandled kernel exception)

Core 0 register dump:
PC      : 0x4000bea8  PS      : 0x00060f33  A0      : 0x8008f1d1  A1      : 0x3ffbde50  
A2      : 0x00000050  A3      : 0x00000000  A4      : 0x3f405144  A5      : 0x3f404ddc  
A6      : 0x00000003  A7      : 0x00060423  A8      : 0x800e26b3  A9      : 0x3ffbe1e0  
A10     : 0x3ffb6678  A11     : 0x3f406025  A12     : 0x3f404ddc  A13     : 0x3f404d70  
A14     : 0x00000069  A15     : 0x3f406018  SAR     : 0x00000018  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000004  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  
Core 0 was running in ISR context:
EPC1    : 0x4000bea8  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x00000000

Backtrace: 0x4000bea8:0x3ffbde50 0x4008f1ce:0x3ffbde70 0x4008f414:0x3ffbde90 0x40081588:0x3ffbdeb0 0x400815b8:0x3ffbded0 0x40081711:0x3ffbdf00 0x400ee26b:0x3ffbdf20 0x400ea4fd:0x3ffbe1e0 0x400e26b0:0x3ffbe230 0x40090131:0x3ffbe260 0x4008f57d:0x3ffbe290 0x400831ec:0x3ffbe2b0 0x40083421:0x3ffbe2e0 0x40081add:0x3ffbe300 0x4016a43b:0x00000000

Rebooting...

Node.js : Passport를 이용한 사용자 인증

Programming/Node.js 2019.02.16 19:18 Posted by 파란크리스마스

출처

/app.js

// 모듈 추가
const passport = require('passport');
const session = require('express-session');
var bodyParser = require('body-parser');

// ... 생략 ...

/*
cookieParser
session
passport.initialize
passport.session
app.route
 */
var app = express();

// ... 생략 ...

app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// 세션 설정
app.use(session({
  secret: 'simpleSNS',
  resave: true,
  saveUninitialized: false
})); // 세션 활성화

require('./config/passport')(passport);
app.use(passport.initialize());
app.use(passport.session()); //로그인 세션 유지

app.use(bodyParser.urlencoded({extended: true}));

/public/login.html

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<form action="/login" method="post">
    <div>
        <label>UserId:</label>
        <input type="text" name="userid"/><br/>
    </div>
    <div>
        <label>Password:</label>
        <input type="password" name="password"/>
    </div>
    <div>
        <input type="submit" value="Submit"/>
    </div>
</form>
</body>
</html>

/config/passport.js

const LocalStrategy = require('passport-local').Strategy;

module.exports = (passport) => {

    // 로그인이 성공하면, serializeUser 메서드를 이용하여 사용자 정보를 Session에 저장할 수 있다.
    passport.serializeUser((user, done) => {
        console.log('serialize');
        done(null, user);
    });

    // 인증 후, 페이지 접근시 마다 사용자 정보를 Session에서 읽어옴.
    passport.deserializeUser((user, done) => {
        console.log('deserialize');
        done(null, user);
    });

    passport.use(new LocalStrategy({
            usernameField : 'userid',
            passwordField : 'password',
            passReqToCallback : true
        },
        
        // 인증 요청
        function(req, userid, password, done) {
            if(userid=='test' && password=='1111') {
                var user = {
                    'userid':'hello',
                    'email':'hello@world.com'
                };
                return done(null, user);
            }else{
                return done(null, false);
            }
        }
    ));
};

/routes/index.js

var express = require('express');
var router = express.Router();
const passport = require('passport');

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

// 로그인
router.post('/login', passport.authenticate('local', {failureRedirect: '/login.html'}), (req, res) => {
  res.redirect('/login_suc.html');
});

/*
router.post('/login', passport.authenticate('local', {
  successRedirect: '/login_suc.html',
  failureRedirect: '/login.html'
}));
*/

// 로그아웃
router.get('/logout', (req, res) => {
  req.logout();
  res.redirect('/');
});

module.exports = router;

Facebook 로그인 적용

/config/passport.js 내용 추가

const FacebookStrategy = require('passport-facebook').Strategy;

module.exports = (passport) => {

// ... 생략 ...

    passport.use(new FacebookStrategy({
            clientID: "",
            clientSecret: "",
            profileFields: ['id', 'displayName', 'photos'],
            callbackURL: 'http://localhost:3000/markdown/auth/facebook/callback'
        },

        function (accessToken, refreshToken, profile, done) {
            const socialId = profile.id;
            const nickname = profile.displayName;
            const profileImageUrl = profile.photos[0].value;

            onLoginSuccess('Facebook', socialId, nickname, profileImageUrl, done);
        }
    ));

/routes/index.js 내용 추가

// ... 생략 ...

// 로그아웃
router.get('/logout', (req, res) => {
  req.logout();
  res.redirect('/');
});

// 페이스북 로그인 시작
router.get('/facebook', passport.authenticate('facebook'));

// 페이스북 로그인 결과 콜백
router.get('/facebook/callback', passport.authenticate('facebook', {
    failureRedirect: '/markdown/auth/login'
}), (req, res) => {
    loginSuccessHandler(req, res);
});

module.exports = router;

WebStorm : express 프로젝트 생성

Programming/Node.js 2019.02.16 19:09 Posted by 파란크리스마스

출처

프로젝트 생성

express 프로젝트 생성

express 프로젝트 실행

실행결과

M5Stack : 오프라인 MicroPython으로 개발하기

OS/M5Stack 2019.02.16 03:13 Posted by 파란크리스마스

M5Stack Korea인 WIZnet에서 운영하는 메이커 컨텐츠 커뮤니티 사이트의 후원을 받아서 작성되었습니다.

출처

M5Stack : 오프라인 MicroPython으로 개발하기

M5Stack은 여러개의 개발언어중 MicroPython으로도 개발이 가능한데, MicroPython의 개발은 온라인 개발과 오프라인 개발 두가지가 있고, 온라인 방법은 많이 나와 있지만, 오프라인 개발은 자료가 많이 없어 정리 해보았습니다.

MicroPythone의 개발은 펌웨어를 업로드 해야 가능하며, 최신버전의 펌웨어로 적용해야 더 많은 함수를 사용할 수 있으므로 항상 최신버전의 펌웨어를 적용하시기 바랍니다.

펌웨어도 온라인과, 오프라인 두가지가 있으므로, 여기에서는 오프라인 펌웨어을 업도하고, Python 파일을 업로드하고 실행해보겠습니다.

esptool 설치 - 펌웨어 관련 도구

C:\M5Stack>pip3 install esptool
Collecting esptool
  Downloading https://files.pythonhosted.org/packages/5c/85/5654e7b9019739d3d89af0adf528c9ae57a9a26682e3aa012e1e30f20674/esptool-2.6.tar.gz (80kB)
    100% |████████████████████████████████| 81kB 457kB/s
Collecting pyserial>=3.0 (from esptool)
  Using cached https://files.pythonhosted.org/packages/0d/e4/2a744dd9e3be04a0c0907414e2a01a7c88bb3915cbe3c8cc06e209f59c30/pyserial-3.4-py2.py3-none-any.whl
Collecting pyaes (from esptool)
  Downloading https://files.pythonhosted.org/packages/44/66/2c17bae31c906613795711fc78045c285048168919ace2220daa372c7d72/pyaes-1.6.1.tar.gz
Collecting ecdsa (from esptool)
  Downloading https://files.pythonhosted.org/packages/63/f4/73669d51825516ce8c43b816c0a6b64cd6eb71d08b99820c00792cb42222/ecdsa-0.13-py2.py3-none-any.whl (86kB)
    100% |████████████████████████████████| 92kB 920kB/s
Installing collected packages: pyserial, pyaes, ecdsa, esptool
  Running setup.py install for pyaes ... done
  Running setup.py install for esptool ... done
Successfully installed ecdsa-0.13 esptool-2.6 pyaes-1.6.1 pyserial-3.4
You are using pip version 18.1, however version 19.0.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

펌웨어 업로드

최신 펌웨어 다운로드

C:\M5Stack>git clone https://github.com/m5stack/M5Cloud.git
Cloning into 'M5Cloud'...
remote: Enumerating objects: 510, done.
remote: Total 510 (delta 0), reused 0 (delta 0), pack-reused 510R
Receiving objects: 100% (510/510), 25.65 MiB | 2.15 MiB/s, done.
Resolving deltas: 100% (230/230), done.

기존 펌웨어 지우기

C:\M5Stack>python.exe -m esptool --port COM13 --baud 921600 --after no_reset erase_flash
esptool.py v2.6
Serial port COM13
Connecting......
Detecting chip type... ESP32
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
MAC: 84:0d:8e:xx:xx:xx
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Erasing flash (this may take a while)...
Chip erase completed successfully in 15.4s
Staying in bootloader.

펌웨어 업로드

C:\M5Stack>cd C:\M5Stack\M5Cloud\firmwares\OFF-LINE

C:\M5Stack\M5Cloud\firmwares\OFF-LINE>python.exe -m esptool --chip esp32 --port COM13 --baud 921600 write_flash -z 0x1000 m5stack-20180516-v0.4.0.bin
esptool.py v2.6
Serial port COM13
Connecting....
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
MAC: 84:0d:8e:xx:xx:xx
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Auto-detected Flash size: 16MB
Flash params set to 0x0240
Compressed 1747296 bytes to 1119059...
Wrote 1747296 bytes (1119059 compressed) at 0x00001000 in 16.7 seconds (effective 838.2 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

ampy(Adafruit MicroPython tool) 설치

C:\M5Stack\M5Cloud\firmwares\OFF-LINE>pip3 install adafruit-ampy
Collecting adafruit-ampy
  Using cached https://files.pythonhosted.org/packages/59/99/f8635577c9a11962ec43714b3fc3d4583070e8f292789b4683979c4abfec/adafruit_ampy-1.0.7-py2.py3-none-any.whl
Requirement already satisfied: pyserial in c:\users\bluesanta\appdata\local\programs\python\python37-32\lib\site-packages (from adafruit-ampy) (3.4)
Collecting click (from adafruit-ampy)
  Using cached https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl
Collecting python-dotenv (from adafruit-ampy)
  Using cached https://files.pythonhosted.org/packages/8c/14/501508b016e7b1ad0eb91bba581e66ad9bfc7c66fcacbb580eaf9bc38458/python_dotenv-0.10.1-py2.py3-none-any.whl
Installing collected packages: click, python-dotenv, adafruit-ampy
Successfully installed adafruit-ampy-1.0.7 click-7.0 python-dotenv-0.10.1
You are using pip version 18.1, however version 19.0.2 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

HelloWord 예제 만들기 (HelloWorld.py)

#from m5 import lcd
from m5stack import lcd

lcd.clear()
lcd.setCursor(0, 0)
lcd.setColor(lcd.WHITE)
lcd.print("Hello world! - http://bluexmas.tistory.com")

HelloWord 업로드

M5Stack 포트 설정

C:\M5Stack>set AMPY_PORT=COM13

HelloWord 업로드

C:\M5Stack>cd HelloWorld

C:\M5Stack\HelloWorld>ampy put ./HelloWorld.py /flash/HelloWorld.py

C:\M5Stack\HelloWorld>ampy run ./HelloWorld.py

HelloWord 실행

M5Stack : Arduino 개발 환경 만들기(개발툴 설치)

OS/M5Stack 2019.02.15 00:17 Posted by 파란크리스마스

M5Stack Korea인 WIZnet에서 운영하는 메이커 컨텐츠 커뮤니티 사이트의 후원을 받아서 작성되었습니다.

출처

M5Stack : Arduino 개발 환경 만들기(개발툴 설치)

M5Stack 드라이버 설치하고, Arduino IDE에 M5Stack 보드와 라이브러리 설치하고, 예제실행까지 해보았습니다.

Arduino IDE로 프로그램 컴파일하고 업로드 했을 경우, M5Stack는 Arduino로 컴파일된 프로그램만 실행 됩니다. 다시 MicroPython이나 UIFlow로 프로그램을 실행 시키시려면 펌웨어를 업로드 해야 됩니다.

M5Stack 드라이버 설치

M5Stack 드라이버 설치전

M5Stack 사이트에서 다운로드 페이지로 이동

M5Stack 사이트에서 Windows 드라이버 다운로드

다운로드 받은 드라이버 설치파일(CP210x_VCP_Windows.zip)을 압출을 풀고 Windows의 버전에 맞는 설치 프로그램 실행

M5Stack 드라이버 설치 과정

  

M5Stack 드라이버 설치후

Arduino IDE 설치

다운로드 주소 : https://www.arduino.cc/en/Main/Software

Arduino IDE에 M5Stack 보드 추가

arduino-esp32 다운로드

Github 저장소(espressif / arduino-esp32)에서 arduino-esp32-1.0.1.zip 파일 다운로드

arduino-esp32 설치

다운로드 받은 파일 arduino-esp32-1.0.1.zip을 [Arduino IDE 설치경로]/hardware/espressif/esp32에 압축 해제

get.exe 실행 파일을 관리자 권한으로 실행

[Arduino IDE 설치경로]/hardware/espressif/esp32/tools 디렉토리에서 get.exe 실행 파일을 관리자 권한으로 실행 실행

Arduino IDE를 실행하고, 메뉴[툴] > [보드] > [M5Stack-Core-ESP32] 선택

메뉴[툴] > [포트] > [COM13] 포트선택

M5Stack 라이브러리 설치

메뉴[툴] > [라이브러리 관리] 선택

M5Stack 라이브러리 설치

[HelloWorld] 예제 선택

예제 실행

예제 실행 결과

M5Stack 개봉기

OS/M5Stack 2019.02.14 00:12 Posted by 파란크리스마스

M5Stack Korea인 WIZnet에서 운영하는 메이커 컨텐츠 커뮤니티 사이트의 후원을 받아서 작성되었습니다.

출처

이번 에 M5Stack 채험단에 선정해주신 WIZnet에 감사드립니다.

아래 사진과 같은 제품이 배송되었습니다.

제품이 안전하게 배송 되도록 에어캡 포장도 잘 되어 있습니다.

체험단 선정시 신청한 4개의 체품도 잘 받습니다.

M5GO Iot Starter Kit, Servo DRIVER MODULE, M5CAMERA, STEPMOTER FUNCTION MODULE

M5GO Iot Starter Kit를 첫 개봉하시면 아래와 같이 구성 되어 있습니다.

간단한 가이드, 레고 테크릭 블럭, M5Stack 본체와 케이블, 6개 모듈이 있는데, 특이한 것은 레고 테크릭 블럭이 있다는 것인데, 대부분의 모듈이 레고 블럭과 연결이 되도록 되어 있습니다.

6개의 모듈은 아래의 순서와 같고, 모듈 커넥터용 케이블과 M5Stack 본체의 연결 데이터 케이블이 있습니다.

1. Mini HUB Unit 1 to 3 HUB with Universal Connector Grove Port
2. Mini Angle Unit Potentiometer Inside Resistance Adjustable
3. Mini PIR Sensor Human Body Infrared PIR Motion Sensor Detector Module
4. Mini Infrared Unit IR Remote Reflective Sensor with Receiver and Transmitter
5. Mini RGB Unit with NeoPixel RGB LED Light x3
6. ENV Unit with DHT12 BMP280 Digital DHT-12 Temperature Humidity Aire Pressure Sensor

M5Stack 본체의 뒤면은 레고블럭 처럼 되어 있습니다.

개발가능한 프로그램 언어

UIFlow
MicroPython
Arduino - Sketch

M5GO Iot Starter Kit 스펙

이미지 출처 : AliExpress M5Stack Store


MariaDB : 수동(zip 버전)설치

Database 2019.02.10 12:29 Posted by 파란크리스마스

출처

MariaDB 서비스 등록

C:\server\mysql\mariadb-10.3.12-winx64>bin\mysql_install_db --datadir=C:\server\mysql\mariadb-10.3.12-winx64\data --service="MariaDB" --port=3306 --password=xxxx
Running bootstrap
2019-02-10 12:39:34 0 [Note] C:\server\mysql\mariadb-10.3.12-winx64\bin\mysqld.exe (mysqld 10.3.12-MariaDB) starting as process 3784 ...
Removing default user
Setting root password
Creating my.ini file
Registering service 'MariaDB 10312'
Creation of the database was successful
C:\server\mysql\mariadb-10.3.12-winx64>

root 사용자 암호등록

C:\server\mysql\mariadb-10.3.12-winx64>bin\mysql -u root -p
Enter password: ******
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 10.3.12-MariaDB mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> use mysql;
Database changed

MariaDB [mysql]> select user, host from mysql.user;
+------+-----------+
| user | host      |
+------+-----------+
| root | 127.0.0.1 |
| root | ::1       |
| root | localhost |
+------+-----------+
3 rows in set (0.004 sec)

MariaDB [mysql]> alter user 'root'@'localhost' identified by 'sqldba';
Query OK, 0 rows affected (0.002 sec)

MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.001 sec)