2020년 6월 18일 목요일
2019년 12월 2일 월요일
Get number of new mails from GMail on Wemos D1 mini ESP8266
Wemos D1 mini ESP8266 을 이용해서 Gmail 의 새편지 갯수 구하기
ESP8266 에서 Gmail 접속을 위해서는 Gmail 의 보안 수준을 설정해야 한다.
새편지가 있으면 숫자를 보여주고 새편지가 없으면 점을 하나 찍는다.
약 2분마다 새편지 확인을 반복한다.
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WiFiClientSecure.h>
#define GMAIL_ID_PW "id@gmail.com:password"
#define WIFI_SSID "wifi_ssid"
#define WIFI_PW "wifi_password"
#define MAX7219_CS 0
#define MAX7219_DIN 2
#define MAX7219_CLK 4
const byte EngFont[8*17] = {
0x00,0x7E,0xFF,0x81,0x81,0xFF,0x7E,0x00, // Number 0
0x00,0x00,0x21,0x7F,0xFF,0x01,0x00,0x00, // Number 1
0x00,0x43,0xC7,0x8D,0x99,0xF1,0x61,0x00, // Number 2
0x00,0x42,0xC3,0x91,0x91,0xFF,0x6E,0x00, // Number 3
0x00,0x0C,0x1C,0x34,0x64,0xFF,0x04,0x00, // Number 4
0x00,0xF2,0xF3,0x91,0x91,0x9F,0x8E,0x00, // Number 5
0x00,0x7E,0xFF,0x91,0x91,0xDF,0x4E,0x00, // Number 6
0x00,0x80,0x80,0x8F,0xBF,0xF0,0xC0,0x00, // Number 7
0x00,0x6E,0xFF,0x91,0x91,0xFF,0x6E,0x00, // Number 8
0x00,0x70,0xF9,0x89,0x89,0xFF,0x7E,0x00, // Number 9
0x00,0x00,0x00,0x06,0x06,0x00,0x00,0x00, // WiFi .
0x00,0x08,0x10,0x16,0x16,0x10,0x08,0x00, // WiFi o
0x20,0x48,0x50,0x56,0x56,0x50,0x48,0x20, // WiFi O
0x7E,0x62,0x52,0x4A,0x4A,0x52,0x62,0x7E, // Mail check
0xF8,0xA8,0xA8,0x00,0x1F,0x12,0x12,0x0C, // Error Parse
0xF8,0xA8,0xA8,0x00,0x0E,0x11,0x11,0x0A, // Error Connect
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 // Empty
};
ESP8266WiFiMulti gWifi;
int gStatus;
int gTic;
int gNum;
byte mPrevChar;
void Max7219Command (byte reg, byte data) {
digitalWrite (MAX7219_CS, LOW);
for (byte i=0; i<8; i++) {
digitalWrite (MAX7219_CLK, LOW);
digitalWrite (MAX7219_DIN, (reg<<i)&128);
digitalWrite (MAX7219_CLK, HIGH);
}
for (byte i=0; i<8; i++) {
digitalWrite (MAX7219_CLK, LOW);
digitalWrite (MAX7219_DIN, (data<<i)&128);
digitalWrite (MAX7219_CLK, HIGH);
}
digitalWrite (MAX7219_CS, HIGH);
digitalWrite (MAX7219_DIN, HIGH);
}
void Max7219Put (byte c) {
mPrevChar = c;
for (int i=0; i<8; i++) {
if (c < 64) Max7219Command (8-i, EngFont[c*8+i]);
else Max7219Command (8-i, ((c>>3)&7)==i ? 128>>(c&7) : 0);
}
}
void Max7219Fade (byte c) {
byte a, b, o=mPrevChar;
delay (0);
for (a=1; a<32; a++) {
for (b=a; b<32; b++) Max7219Put (o);
for (b=0; b< a; b++) Max7219Put (c);
}
}
void Max7219Bf (byte c) {
Max7219Fade (16);
Max7219Fade (c);
}
const char int2base[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void Text2Base64 (const char *rp, char *wp) {
int i, len, bits;
for (len=strlen(rp); 0<len; len-=3) {
for (i=0; i<3; i++) ((char *)&bits)[2-i] = (i < len) ? *rp++ : 0;
for (i=0; i<4; i++) *wp++ = (len < i) ? '=' : int2base[(bits>>((3-i)*6))&63];
}
*wp = 0;
}
int GetGmailHttp () {
WiFiClientSecure client;
char base64[64];
int num;
client.setInsecure ();
if (!client.connect ("mail.google.com", 443)) return 15;
Text2Base64 (GMAIL_ID_PW, base64);
client.print (
"GET /mail/feed/atom HTTP/1.1\r\n"
"Host: mail.google.com\r\n"
"Connection: close\r\n"
"Authorization: Basic "
);
client.print (base64);
client.print ("\r\n\r\n");
num = 14;
while (client.connected ()) {
client.readStringUntil ('<');
String tn = client.readStringUntil ('<');
if (tn == "fullcount") {
num = client.readStringUntil ('<').toInt ();
if (9 < num) num = 9;
break;
}
}
client.stop ();
return num;
}
void loop() {
delay (1000);
if (gWifi.run () != WL_CONNECTED) {
gStatus = 0;
gTic = (gTic+1) % 3;
Max7219Fade (10+gTic);
return;
}
if (gStatus == 0) {
gStatus = 1;
gTic = -1;
gNum = -1;
}
gTic = (gTic + 1) & 63;
if (gNum == 0) Max7219Bf (64+gTic);
if (gTic) {
if (0 < gNum) Max7219Bf (gNum);
return;
}
if (gNum) Max7219Bf (13);
gNum = GetGmailHttp ();
if (gNum == 0) Max7219Bf (64+(++gTic));
else Max7219Bf (gNum);
}
void setup() {
gStatus = 0;
gTic = 0;
pinMode (MAX7219_DIN, OUTPUT);
pinMode (MAX7219_CLK, OUTPUT);
pinMode (MAX7219_CS, OUTPUT);
digitalWrite (MAX7219_DIN, HIGH);
digitalWrite (MAX7219_CLK, HIGH);
digitalWrite (MAX7219_CS, HIGH);
delay (50);
Max7219Command (12, 1);
Max7219Command (11, 7);
Max7219Command ( 9, 0);
Max7219Command (15, 0);
Max7219Command (10, 0);
Max7219Command (12, 1);
Max7219Put (16);
gWifi.addAP (WIFI_SSID, WIFI_PW);
delay (500);
Max7219Fade (10);
}
ESP8266 에서 Gmail 접속을 위해서는 Gmail 의 보안 수준을 설정해야 한다.
https://myaccount.google.com/lesssecureapps 에서 'ON'8x8 도트매트릭스 MAX7219는 SPI로 통신하는데 핀제어로 자료를 보낸다.
5V - MAX7219 VCC전원인가후 WiFi 에 접속하고, Gmail 에 접속해서 새편지 갯수를 가져온다.
GND - MAX7219 GND
PIN2 - MAX7219 DIN (MOSI)
PIN0 - MAX7219 CS
PIN4 - MAX7219 CLK
새편지가 있으면 숫자를 보여주고 새편지가 없으면 점을 하나 찍는다.
약 2분마다 새편지 확인을 반복한다.
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WiFiClientSecure.h>
#define GMAIL_ID_PW "id@gmail.com:password"
#define WIFI_SSID "wifi_ssid"
#define WIFI_PW "wifi_password"
#define MAX7219_CS 0
#define MAX7219_DIN 2
#define MAX7219_CLK 4
const byte EngFont[8*17] = {
0x00,0x7E,0xFF,0x81,0x81,0xFF,0x7E,0x00, // Number 0
0x00,0x00,0x21,0x7F,0xFF,0x01,0x00,0x00, // Number 1
0x00,0x43,0xC7,0x8D,0x99,0xF1,0x61,0x00, // Number 2
0x00,0x42,0xC3,0x91,0x91,0xFF,0x6E,0x00, // Number 3
0x00,0x0C,0x1C,0x34,0x64,0xFF,0x04,0x00, // Number 4
0x00,0xF2,0xF3,0x91,0x91,0x9F,0x8E,0x00, // Number 5
0x00,0x7E,0xFF,0x91,0x91,0xDF,0x4E,0x00, // Number 6
0x00,0x80,0x80,0x8F,0xBF,0xF0,0xC0,0x00, // Number 7
0x00,0x6E,0xFF,0x91,0x91,0xFF,0x6E,0x00, // Number 8
0x00,0x70,0xF9,0x89,0x89,0xFF,0x7E,0x00, // Number 9
0x00,0x00,0x00,0x06,0x06,0x00,0x00,0x00, // WiFi .
0x00,0x08,0x10,0x16,0x16,0x10,0x08,0x00, // WiFi o
0x20,0x48,0x50,0x56,0x56,0x50,0x48,0x20, // WiFi O
0x7E,0x62,0x52,0x4A,0x4A,0x52,0x62,0x7E, // Mail check
0xF8,0xA8,0xA8,0x00,0x1F,0x12,0x12,0x0C, // Error Parse
0xF8,0xA8,0xA8,0x00,0x0E,0x11,0x11,0x0A, // Error Connect
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 // Empty
};
ESP8266WiFiMulti gWifi;
int gStatus;
int gTic;
int gNum;
byte mPrevChar;
void Max7219Command (byte reg, byte data) {
digitalWrite (MAX7219_CS, LOW);
for (byte i=0; i<8; i++) {
digitalWrite (MAX7219_CLK, LOW);
digitalWrite (MAX7219_DIN, (reg<<i)&128);
digitalWrite (MAX7219_CLK, HIGH);
}
for (byte i=0; i<8; i++) {
digitalWrite (MAX7219_CLK, LOW);
digitalWrite (MAX7219_DIN, (data<<i)&128);
digitalWrite (MAX7219_CLK, HIGH);
}
digitalWrite (MAX7219_CS, HIGH);
digitalWrite (MAX7219_DIN, HIGH);
}
void Max7219Put (byte c) {
mPrevChar = c;
for (int i=0; i<8; i++) {
if (c < 64) Max7219Command (8-i, EngFont[c*8+i]);
else Max7219Command (8-i, ((c>>3)&7)==i ? 128>>(c&7) : 0);
}
}
void Max7219Fade (byte c) {
byte a, b, o=mPrevChar;
delay (0);
for (a=1; a<32; a++) {
for (b=a; b<32; b++) Max7219Put (o);
for (b=0; b< a; b++) Max7219Put (c);
}
}
void Max7219Bf (byte c) {
Max7219Fade (16);
Max7219Fade (c);
}
const char int2base[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void Text2Base64 (const char *rp, char *wp) {
int i, len, bits;
for (len=strlen(rp); 0<len; len-=3) {
for (i=0; i<3; i++) ((char *)&bits)[2-i] = (i < len) ? *rp++ : 0;
for (i=0; i<4; i++) *wp++ = (len < i) ? '=' : int2base[(bits>>((3-i)*6))&63];
}
*wp = 0;
}
int GetGmailHttp () {
WiFiClientSecure client;
char base64[64];
int num;
client.setInsecure ();
if (!client.connect ("mail.google.com", 443)) return 15;
Text2Base64 (GMAIL_ID_PW, base64);
client.print (
"GET /mail/feed/atom HTTP/1.1\r\n"
"Host: mail.google.com\r\n"
"Connection: close\r\n"
"Authorization: Basic "
);
client.print (base64);
client.print ("\r\n\r\n");
num = 14;
while (client.connected ()) {
client.readStringUntil ('<');
String tn = client.readStringUntil ('<');
if (tn == "fullcount") {
num = client.readStringUntil ('<').toInt ();
if (9 < num) num = 9;
break;
}
}
client.stop ();
return num;
}
void loop() {
delay (1000);
if (gWifi.run () != WL_CONNECTED) {
gStatus = 0;
gTic = (gTic+1) % 3;
Max7219Fade (10+gTic);
return;
}
if (gStatus == 0) {
gStatus = 1;
gTic = -1;
gNum = -1;
}
gTic = (gTic + 1) & 63;
if (gNum == 0) Max7219Bf (64+gTic);
if (gTic) {
if (0 < gNum) Max7219Bf (gNum);
return;
}
if (gNum) Max7219Bf (13);
gNum = GetGmailHttp ();
if (gNum == 0) Max7219Bf (64+(++gTic));
else Max7219Bf (gNum);
}
void setup() {
gStatus = 0;
gTic = 0;
pinMode (MAX7219_DIN, OUTPUT);
pinMode (MAX7219_CLK, OUTPUT);
pinMode (MAX7219_CS, OUTPUT);
digitalWrite (MAX7219_DIN, HIGH);
digitalWrite (MAX7219_CLK, HIGH);
digitalWrite (MAX7219_CS, HIGH);
delay (50);
Max7219Command (12, 1);
Max7219Command (11, 7);
Max7219Command ( 9, 0);
Max7219Command (15, 0);
Max7219Command (10, 0);
Max7219Command (12, 1);
Max7219Put (16);
gWifi.addAP (WIFI_SSID, WIFI_PW);
delay (500);
Max7219Fade (10);
}
2019년 10월 31일 목요일
2019년 4월 1일 월요일
Wemos D1 mini ESP8266 WiFiClient NonBlocking
Wemos D1 mini : 저렴한 가격 + 작은 크기 + WiFi + Arduino
WiFi 로 Server 에 접속할때 connect 명령에서 최대 5초간 멈춤이 발생한다.
NonBlocking, Asynchronous connect 명령을 만들었다.
해결방법:
esp8266 라이브러리 폴더를 찾는다.
C:/Users/UserID/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.5.0/libraries/ESP8266WiFi/src
1. WiFiClient.h 59line 에 추가.
int connectAsync(const char* host, uint16_t port);
int connectCheck();
2. WiFiClient.cpp 182line 에 추가.
int WiFiClient::connectAsync(const char* host, uint16_t port) {
IPAddress ip;
if (!WiFi.hostByName(host, ip, _timeout)) return 0;
if (_client) {
stop();
_client->unref();
_client = nullptr;
}
#if LWIP_VERSION_MAJOR == 1
netif* interface = ip_route(ip);
if (!interface) {
DEBUGV("no route to host\r\n");
return 0;
}
#endif
tcp_pcb* pcb = tcp_new();
if (!pcb) return 0;
if (_localPort > 0) pcb->local_port = _localPort++;
_client = new ClientContext(pcb, nullptr, nullptr);
_client->ref();
_client->setTimeout(_timeout);
int res = _client->connectAsync(ip, port);
if (res == 0) {
_client->unref();
_client = nullptr;
return 0;
}
return 1;
}
int WiFiClient::connectCheck() {
int res = _client->connectCheck();
if (res == 0) return 0;
if (res == -1) {
_client->unref();
_client = nullptr;
return -1;
}
setSync(defaultSync);
setNoDelay(defaultNoDelay);
return 1;
}
3. include/ClientContext.h 147line 에 추가.
int connectAsync(CONST ip_addr_t* addr, uint16_t port) {
err_t err = tcp_connect (_pcb, addr, port, &ClientContext::_s_connected);
if (err != ERR_OK) return 0;
_op_start_time = millis();
return 1;
}
int connectCheck() {
if (!_pcb) return -1;
if (_pcb->state == ESTABLISHED) return 1;
if (millis() - _op_start_time < _timeout_ms) return 0;
abort();
return -1;
}
4. include/ClientContext.h 수정
함수
err_t _connected(struct tcp_pcb *pcb, err_t err)
의
assert(_connect_pending);
esp_schedule();
를
if (_connect_pending) esp_schedule();
로 변경
사용방법:
WiFiClient client;
int rv;
if (client.connectAsync ("192.168.1.2", 123) == 0) return -1;
do {
rv = client.connectCheck ();
if (rv == -1) return -1;
if (rv == 1) break;
delay (1);
} while (rv == 0);
len = client.available ();
if (0 < len) len = client.read (buff, len);
len = client.availableForWrite ();
if (0 < len) len = client.write (buff, len);
WiFi 로 Server 에 접속할때 connect 명령에서 최대 5초간 멈춤이 발생한다.
NonBlocking, Asynchronous connect 명령을 만들었다.
해결방법:
esp8266 라이브러리 폴더를 찾는다.
C:/Users/UserID/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.5.0/libraries/ESP8266WiFi/src
1. WiFiClient.h 59line 에 추가.
int connectAsync(const char* host, uint16_t port);
int connectCheck();
2. WiFiClient.cpp 182line 에 추가.
int WiFiClient::connectAsync(const char* host, uint16_t port) {
IPAddress ip;
if (!WiFi.hostByName(host, ip, _timeout)) return 0;
if (_client) {
stop();
_client->unref();
_client = nullptr;
}
#if LWIP_VERSION_MAJOR == 1
netif* interface = ip_route(ip);
if (!interface) {
DEBUGV("no route to host\r\n");
return 0;
}
#endif
tcp_pcb* pcb = tcp_new();
if (!pcb) return 0;
if (_localPort > 0) pcb->local_port = _localPort++;
_client = new ClientContext(pcb, nullptr, nullptr);
_client->ref();
_client->setTimeout(_timeout);
int res = _client->connectAsync(ip, port);
if (res == 0) {
_client->unref();
_client = nullptr;
return 0;
}
return 1;
}
int WiFiClient::connectCheck() {
int res = _client->connectCheck();
if (res == 0) return 0;
if (res == -1) {
_client->unref();
_client = nullptr;
return -1;
}
setSync(defaultSync);
setNoDelay(defaultNoDelay);
return 1;
}
3. include/ClientContext.h 147line 에 추가.
int connectAsync(CONST ip_addr_t* addr, uint16_t port) {
err_t err = tcp_connect (_pcb, addr, port, &ClientContext::_s_connected);
if (err != ERR_OK) return 0;
_op_start_time = millis();
return 1;
}
int connectCheck() {
if (!_pcb) return -1;
if (_pcb->state == ESTABLISHED) return 1;
if (millis() - _op_start_time < _timeout_ms) return 0;
abort();
return -1;
}
4. include/ClientContext.h 수정
함수
err_t _connected(struct tcp_pcb *pcb, err_t err)
의
assert(_connect_pending);
esp_schedule();
를
if (_connect_pending) esp_schedule();
로 변경
사용방법:
WiFiClient client;
int rv;
if (client.connectAsync ("192.168.1.2", 123) == 0) return -1;
do {
rv = client.connectCheck ();
if (rv == -1) return -1;
if (rv == 1) break;
delay (1);
} while (rv == 0);
len = client.available ();
if (0 < len) len = client.read (buff, len);
len = client.availableForWrite ();
if (0 < len) len = client.write (buff, len);
2018년 9월 17일 월요일
라즈베리 파이를 이용한 원격 자료수집기
라즈베리 파이3 을 이용해서 범용 센서 정보수집 장치를 만들었다.
C 와 C++ 로 만들었으며, 웹서버를 내장하고 있다.
센서 보드와 시리얼(TTL) 모드버스 방식으로 통신한다.
수집한 자료는 PCA(Principal Component Analysis), LDA(Linear Discriminant Analysis), Pattern, Neural Network 분석이 가능하고,
KT IoT, Microsoft Azure, HTTP POST, MQTT 등 프로토콜을 이용해서 서버로 발송한다.
자료는 내장 SD카드에도 저장하는데, 저장 간격에 따라서 다르기는 하지만 약 10년 치를 저장할 수 있다.
원활한 관리를 위하여 원격에서 서버를 라즈베리파이를 제어할 수도 있는데 SSH, Telnet, HTTP, 원격데스크탑을 지원한다.
특징 :
사용자에게 표출되는 측정 화면의 편집이 가능하다.
모든 처리는 내장 스크립트 언어에서 수행한다.
스크립트 언어는 C 나 Javascript 와 유사하나 아주 단순한 구조로 되어 있다.
스크립트를 수정함으로써 다양한 상황에 유연하게 대처할 수 있다.
C 와 C++ 로 만들었으며, 웹서버를 내장하고 있다.
센서 보드와 시리얼(TTL) 모드버스 방식으로 통신한다.
수집한 자료는 PCA(Principal Component Analysis), LDA(Linear Discriminant Analysis), Pattern, Neural Network 분석이 가능하고,
KT IoT, Microsoft Azure, HTTP POST, MQTT 등 프로토콜을 이용해서 서버로 발송한다.
자료는 내장 SD카드에도 저장하는데, 저장 간격에 따라서 다르기는 하지만 약 10년 치를 저장할 수 있다.
원활한 관리를 위하여 원격에서 서버를 라즈베리파이를 제어할 수도 있는데 SSH, Telnet, HTTP, 원격데스크탑을 지원한다.
특징 :
사용자에게 표출되는 측정 화면의 편집이 가능하다.
모든 처리는 내장 스크립트 언어에서 수행한다.
스크립트 언어는 C 나 Javascript 와 유사하나 아주 단순한 구조로 되어 있다.
스크립트를 수정함으로써 다양한 상황에 유연하게 대처할 수 있다.
2018년 8월 3일 금요일
FileZilla FTP Server 한글 지원
FileZilla_Server-0_9_34.exe 를 설치하고, 윈도우 탐색기에서 FTP 로 접근하면 한글 파일 송/수신이 안된다.
ControlSocket.cpp 수정내용:
88line
m_useUTF8 = true; 를 -> m_useUTF8 = false; 로 변경
2301line
if (args == _T("UTF8 ON")) { } 부분 사용 안함.
모니터 프로그램의 폰트가 마음에 안들어서 변경 :
interface/StatusCtrl.cpp 수정내용:
295line
DEFAULT_GUI_FONT 를 -> SYSTEM_FIXED_FONT 로 변경
컴파일 :
1. FileZilla_Server-0_9_34/zlib/ 필요시 컴파일 한다.
생성파일:
Release/zlib.lib
2. FileZilla_Server-0_9_34 컴파일 한다.
생성파일:
Release/FileZilla server.exe
interface/Release/FileZilla Server Interface.exe
ControlSocket.cpp 수정내용:
88line
m_useUTF8 = true; 를 -> m_useUTF8 = false; 로 변경
2301line
if (args == _T("UTF8 ON")) { } 부분 사용 안함.
모니터 프로그램의 폰트가 마음에 안들어서 변경 :
interface/StatusCtrl.cpp 수정내용:
295line
DEFAULT_GUI_FONT 를 -> SYSTEM_FIXED_FONT 로 변경
컴파일 :
1. FileZilla_Server-0_9_34/zlib/ 필요시 컴파일 한다.
생성파일:
Release/zlib.lib
2. FileZilla_Server-0_9_34 컴파일 한다.
생성파일:
Release/FileZilla server.exe
interface/Release/FileZilla Server Interface.exe
2017년 6월 26일 월요일
2016년 12월 20일 화요일
2016년 10월 18일 화요일
WiFi SSID 에 따라서 자동으로 IP 설정을 변경하기.
작업용으로 사용하는 노트북을 집에서는 고정 IP, 회사에서는 유동 아이피로 사용하고 있다.
매번 수동으로 IP 와 DNS 를 설정하는 것이 번거로우므로 간단한 해결책을 만들었다.
@echo off
for /f %%i in ('netsh wlan show interface ^| find /C "SSID_NAME"') do (set X=%%i)
if %X% == 0 (
netsh interface ipv4 set address name="Wi-Fi" source=dhcp
timeout 1 >nul
netsh interface ipv4 set dnsservers name="Wi-Fi" source=dhcp
) else (
netsh interface ipv4 set address name="Wi-Fi" source=static address=192.168.219.73 mask=255.255.255.0 gateway=192.168.219.1 gwmetric=1
timeout 1 >nul
netsh interface ipv4 set dnsservers name="Wi-Fi" source=static address=1.214.68.2 register=primary validate=no
timeout 1 >nul
netsh interface ipv4 add dnsservers name="Wi-Fi" address=61.41.153.2 validate=no
)
매번 수동으로 IP 와 DNS 를 설정하는 것이 번거로우므로 간단한 해결책을 만들었다.
Step1. WiFiAutoConfig.bat 파일을 적당한 곳에 만든다.
@echo off
for /f %%i in ('netsh wlan show interface ^| find /C "SSID_NAME"') do (set X=%%i)
if %X% == 0 (
netsh interface ipv4 set address name="Wi-Fi" source=dhcp
timeout 1 >nul
netsh interface ipv4 set dnsservers name="Wi-Fi" source=dhcp
) else (
netsh interface ipv4 set address name="Wi-Fi" source=static address=192.168.219.73 mask=255.255.255.0 gateway=192.168.219.1 gwmetric=1
timeout 1 >nul
netsh interface ipv4 set dnsservers name="Wi-Fi" source=static address=1.214.68.2 register=primary validate=no
timeout 1 >nul
netsh interface ipv4 add dnsservers name="Wi-Fi" address=61.41.153.2 validate=no
)
- "SSID_NAME" 에는 고정 IP로 사용하고자 하는 곳의 SSID 를 적는다.
- "Wi-Fi" 이 이름은 PC에 따라서 다를 수 있다.
- IP, SubnetMask, Gateway, DNS 등은 적당하게 설정한다.
Step2. Windows 작업 스케줄러에 등록한다.
제어판 → 관리 도구 → 작업 스케줄러 → 작업 만들기
일반탭
- 이름 : "WiFi 자동 설정"
- [선택] 사용자의 로그온 여부에 관계없이 실행
- [체크] 가장 높은 수준의 권한으로 실행
트리거탭 → 새로 만들기
- 작업 시작 : 이벤트 상태
- 로그 : Microsoft-Windows-WLAN-AutoConfig/Operational
- 원본 : WLAN-AutoConfig
- 이벤트 : 8001
- 고급설정 : [체크] 사용
동작탭 → 새로 만들기
- 찾아보기 → WiFiAutoConfig.bat 선택
조건탭
- 전원쪽은 모두 선택 해제하고,
- [체크] 다음 네트워크 연결을 사용할 수 있는 경우에만 시작 → "모든 연결"
끝.
2016년 10월 17일 월요일
윈도우 CE 원격제어
원격지의 Windows CE 장비 또는 Raspberry PI 장비를 모니터링 한다.
RelayServer:
Client PC 와 원격지 장비간의 통신 중계하는 서버프로그램.
CeMonitor:
PC에서 원격지 장비에 접속할 때 사용하는 프로그램.
CeRemote:
Windows CE 장비에서 원격접속 지원을 위한 프로그램.
TCP, WCDMA, Serial 을 지원한다.
PiRemote:
Raspberry PI 장비에서 원격접속 지원을 위한 프로그램.
TCP 만 지원한다.
RelayServer:
Client PC 와 원격지 장비간의 통신 중계하는 서버프로그램.
CeMonitor:
PC에서 원격지 장비에 접속할 때 사용하는 프로그램.
CeRemote:
Windows CE 장비에서 원격접속 지원을 위한 프로그램.
TCP, WCDMA, Serial 을 지원한다.
PiRemote:
Raspberry PI 장비에서 원격접속 지원을 위한 프로그램.
TCP 만 지원한다.
CeMonitor 실행 화면. 좌측에 접속 가능한 장비 목록이 보인다.
Windows CE 장비에 접속한 상태. 마우스와 키보드를 사용할 수 있다.
Windows CE 장비에 접속한 상태. 마우스와 키보드를 사용할 수 있다.
Raspberry PI 장비에 접속한 상태. 웹브라우저로 접속할 수 있다.
2015년 12월 3일 목요일
Windows 10 에서 오래된 hlp 파일 보기
조건:
Windows 7 에서 잘 동작하던 hlp 파일을 windows 10 으로 업그레이드후에는 열수가 없다.
기존 윈도우 백업에 있는 Windows.old/Windows/winhlp32.exe 는 잘 동작한다.
1. 기존 Windows.old/Windows/winhlp32.exe 파일을 적당한 위치(c:/temp)로 복사한다.
2. Win10-Hlp32-Fix.cmd 파일을 같은 폴더에 만들고 아래와 같이 넣는다.
@echo off
set crtpth=%CD%
takeown /f "%windir%\winhlp32.exe" >nul
icacls "%windir%\winhlp32.exe" /grant *S-1-5-32-544:F >nul
copy /y "%crtpth%\winhlp32.exe" %windir%
icacls "%windir%\winhlp32.exe" /setowner "NT Service\TrustedInstaller" >nul
echo.
echo Done.
echo.
echo Press any key to Exit
pause >nul
exit
3. Win10-Hlp32-Fix.cmd 파일을 관리자 모드로 실행시킨다.
잘 동작하면 끝.
4. hlp 파일을 열때 9009 에러가 발생하면, 기존 Windows.old/Windows/ko-KR/winhlp32.exe.mui 파일을 Windows/ko-KR 로 복사한다.
끝.
Windows 7 에서 잘 동작하던 hlp 파일을 windows 10 으로 업그레이드후에는 열수가 없다.
기존 윈도우 백업에 있는 Windows.old/Windows/winhlp32.exe 는 잘 동작한다.
1. 기존 Windows.old/Windows/winhlp32.exe 파일을 적당한 위치(c:/temp)로 복사한다.
2. Win10-Hlp32-Fix.cmd 파일을 같은 폴더에 만들고 아래와 같이 넣는다.
@echo off
set crtpth=%CD%
takeown /f "%windir%\winhlp32.exe" >nul
icacls "%windir%\winhlp32.exe" /grant *S-1-5-32-544:F >nul
copy /y "%crtpth%\winhlp32.exe" %windir%
icacls "%windir%\winhlp32.exe" /setowner "NT Service\TrustedInstaller" >nul
echo.
echo Done.
echo.
echo Press any key to Exit
pause >nul
exit
3. Win10-Hlp32-Fix.cmd 파일을 관리자 모드로 실행시킨다.
잘 동작하면 끝.
4. hlp 파일을 열때 9009 에러가 발생하면, 기존 Windows.old/Windows/ko-KR/winhlp32.exe.mui 파일을 Windows/ko-KR 로 복사한다.
끝.
2015년 7월 21일 화요일
수비드 장치 만들기
최현석 셰프의 "수비드공법 삼겹살 만드는 법" 을 보고 나도 따라 하고 싶어서
집에 있는 튀김기에 물을 넣고 테스트해보니 +-10도 정도 오차가 나더군요.
그래서 옆에 앉아서 온도계를 보면서 수동으로 3분마다 5초씩 전원을 켰다고 껐다가 하니
수비드 기계를 사려고 했는데 잘 팔지도 않고 가격도 비싸서 만들기로 했습니다.
수조와 히터 역할을 하는 튀김기는 있으니까
전원을 껐다가 켜줄 릴레이와 온도계, 컨트롤러만 있으면 됩니다.
국내에서 이것들을 사려면 5만 원을 훌쩍 넘어가더군요.
알리로 GO GO.
아두이노 우노 R3 호환품 $2.98
2.4인치 터치 LCD 디스플레이 $4.87
온도센서 DS18b20 $1.64
릴레이 $1.5
합계 $10.99. 다음 달 카드 명세를 보니까 12,419원이네요.
모두 다른 판매자로부터 구매했는데 무료배송 상품만 골랐습니다.
국내는 배송비만 최소 2,500원인데, 알리는 중국에서 오면서도 무료이지만
배송에 4주 걸렸습니다. ㅠㅠ
컨트롤러로 사용할 아두이노 우노 R3 호환품은 이탈리아 정품과 비교하면 살짝 다른데
좌우에 핀 구멍이 있어서 작업하기에 상당히 편리합니다.
요건 MADE IN ITALY 입니다. 광센서 테스트중.
LCD는 아두이노 우노랑 핀맵이 같아서 그냥 올리면 됩니다.
* LCD를 사용하기 위해서는 Adafruit_GFX, SWTFT, TouchScreen 라이브러리가 필요한데,
에서 얻을 수 있습니다.
온도센서 DS18b20 는 4.7K 저항으로 풀업해서 핀A5 에 연결했습니다.
* 온도값을 얻기 위해서 OneWire 라이브러리를 사용했습니다.
전선 3가닥(+5V, GND, 제어선A5)을 보드에 납땜하면 되지만 사용의 편의를 위해서
이어폰 잭을 이용해서 분리할 수 있도록 했습니다.
릴레이 제어를 위해서는 핀0, 핀1을 사용했습니다.
하나의 핀만 사용해도 됩니다. 저는 그냥 2개 사용했습니다.
* 핀0,1 은 프로그램 다운로드용으로 사용하기 때문에 일반적으로 사용하지 않습니다.
빈 곳을 찾다 보니까 이곳을 사용하게 되었네요.
전선 4가닥(+5V, GND, 제어선0, 제어선1)은 보드에 납땜했습니다.
히터로 사용할 튀김기가 220V, 3.7A 를 사용하기 때문에 이 정도면 충분합니다.
휘리릭 연결해서 테스트해보니까 +- 0.1도 정도로 조절 됩니다.
온도계 정밀도가 1/16도 이기 때문에 더 높은 정확도는 어렵습니다.
* 디지털 온도계이긴 하지만 정확하지는 않습니다. 반드시 켈리브레이션이 필요합니다.
제가 구매한 놈은 25도에서는 정확하지만 60도에서는 0.15도 낮은 값이 나왔습니다.
마지막으로 튀김기에 보드를 탈착할 수 있도록 만들었습니다.
전면에 보드 연결을 위한 소켓을 만들고
후면에 온도 센서를 위한 이어폰 소켓을 달고
완성!











































