레이블이 프로그래밍인 게시물을 표시합니다. 모든 게시물 표시
레이블이 프로그래밍인 게시물을 표시합니다. 모든 게시물 표시

2020년 6월 18일 목요일

D1 mini Pro + SHT30

D1 mini Pro 에 SHT30 Shield 를 연결했다.
웹서버를 내장해서 PC나 휴대폰에서 웹브라우저로 접근할 수 있다.
1초마다 온도와 습도를 수집하고, 1분 평균을 저장한다.
최대 1일 자료를 볼 수 있다.


2019년 12월 2일 월요일

Get number of new mails from GMail on Wemos D1 mini ESP8266

Wemos D1 mini ESP8266 을 이용해서 Gmail 의 새편지 갯수 구하기


ESP8266 에서 Gmail 접속을 위해서는 Gmail 의 보안 수준을 설정해야 한다.
https://myaccount.google.com/lesssecureapps 에서 'ON'
8x8 도트매트릭스 MAX7219는 SPI로 통신하는데 핀제어로 자료를 보낸다.
5V    - MAX7219 VCC
GND - MAX7219 GND
PIN2 - MAX7219 DIN (MOSI)
PIN0 - MAX7219 CS
PIN4 - MAX7219 CLK
전원인가후 WiFi 에 접속하고, 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);
}

2015년 7월 21일 화요일

수비드 장치 만들기

최현석 셰프의 "수비드공법 삼겹살 만드는 법" 을 보고 나도 따라 하고 싶어서
집에 있는 튀김기에 물을 넣고 테스트해보니 +-10도 정도 오차가 나더군요.
그래서 옆에 앉아서 온도계를 보면서 수동으로 3분마다 5초씩 전원을 켰다고 껐다가 하니
오차는 +-0.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도 낮은 값이 나왔습니다.



마지막으로 튀김기에 보드를 탈착할 수 있도록 만들었습니다.


전면에 보드 연결을 위한 소켓을 만들고





후면에 온도 센서를 위한 이어폰 소켓을 달고




완성!

2015년 6월 17일 수요일

원주율을 계산해보자.

간단한 방법으로 원주율을 계산해봤습니다.
많이 알려진 방법이지만 직접 해보는 게 중요하니까요.


정의:
반지름 1인 원의 면적은 π.

방법:
위 그래프를 아주 작게, 가로 세로 n 개로 나눠서 원점(0,0)에서 거리가 1 미만이면 원에 포함 되는 것으로 한다.

double CalcPi (int n) { // n : 분할 개수
double dv, da, pi, x, y;
  dv = 2.0 / n; // 나눈 점의 크기
  da = dv * dv; // 나눈 점의 면적
  pi = 0; // 원의 면적
  for (x = -1; x < 1; x += dv) { // x 축으로 n 번
    for (y = -1; y < 1; y += dv) {    // y 축으로 n 번, 총 n*n 번 계산
      if (x*x + y*y < 1) { // 원점에서 거리가 1 미만이면
      pi += da; // 면적 추가
      }
    }
  }
return pi;
}

결과:
10 개로 분할 (백 번 계산)
printf ( "π = %f\n", CalcPi (10) );
π = 3.000000
100 개로 분할 (만 번 계산)
printf ( "π = %f\n", CalcPi (100) );
π = 3.135600
1,000 개로 분할 (백만 번 계산)
printf ( "π = %f\n", CalcPi (1000) );
π = 3.141364
10,000 개로 분할 (일억 번 계산)
printf ( "π = %f\n", CalcPi (10000) );
π = 3.141587
100,000 개로 분할 (백억 번 계산)
printf ( "π = %f\n", CalcPi (100000) );
π = 3.141592

백억 번 계산하면 컴퓨터가 힘들어합니다.
4년 된 i5-2430M 노트북으로 24초 걸렸습니다. ^^;

* * *

6월 18일 추가



최적화를 조금 넣었습니다.원의 1/4만 계산하고, 불필요한 계산을 빼서 복잡도를 O(n) 으로 줄였습니다.

double CalcPi2 (int n) {
    int n2, pi, x, y;

   n2 = n*n;
    pi = x = 0;
    for (y=n; 0 < y; y--) {
        for (pi+=x; x < n; x++) {
            if (x*x + y*y <= n2) pi++;
            else break;
        }
    }
    return pi*4.0/n2;
}

10,000 개로 분할 (만 번 계산)
printf ("π = %f\n", CalcPi2 (10000));
π = 3.141591

2015년 4월 10일 금요일

인터넷에서 이걸 봤다.

인터넷에서 이걸 봤다.

출처: 사진에 있음.

우와~ 대박.
나도 그려봐야지.

나는 TI-89 가 없는데?
그럼 만들어야지.



C 를 꺼내서 뚝딱뚝딱.



void Draw2XGraph (double a, double b, double c) {
double x, y;
for (x=X1; x<X2; x+=STEP) {
if (x*x <= b) {
y = a * sqrt(b-(x*x))+c;
DrawPlot (x, y);
}
}
}

void Draw1XGraph (double a, double b, double x1, double x2) {
double x, y;
for (x=x1; x<x2; x+=STEP) {
y = a * x + b;
DrawPlot (x, y);
}
}

void Draw () {
Draw2XGraph (+1, 16, -6);
Draw2XGraph (-1, 16, -6);
Draw2XGraph (+1,  9, +1);
Draw2XGraph (-1,  9, +1);
Draw2XGraph (+1,  4, +3);
Draw2XGraph (-1,  4, +3);
Draw1XGraph (+1, -3, +3, +6);
Draw1XGraph (-1, -3, -6, -3);
}

<일부코드는 생략>


짜잔~~~




이거 올린사람 나와!

2012년 12월 14일 금요일

One Click Timer

https://play.google.com/store/apps/details?id=com.pjw.oct

Easy to Use simple timer.
Timer setting is very simple.
Timer can be started with a single click.
Can set the alarm types and repeat cycle.
You can draw a simple note.

It also provides a counter function.

Does not show ads, does not require any unnecessary permissions.


2012년 6월 14일 목요일

Status bar Calendar

https://play.google.com/store/apps/details?id=com.pjw.sbcd
https://play.google.com/store/apps/details?id=com.pjw.sbc

상태 표시줄 달력

상태 표시줄 달력은 상태바에 요일과 날자를 보여줍니다.

아이콘과 날자형식, 설명, 클릭 동작등을 설정할 수 있습니다.

*** 이 앱을 사용하려면, 알 수 없는 소스를 설치할 수 있는 권한이 필요합니다.
*** ( 시스템 설정 - 보안 - 알 수 없는 소스 [체크] )
*** 아이콘을 설치 한 후, 안전을 위해 설정을 복원하세요.

*** 블루 스크린 필터를 사용하는 경우, 아이콘을 설치할 수 없습니다. 아이콘 설치를 위해서 필터를 해제하시기 바랍니다.

기능

1. 상태표시줄에 월 또는 요일과 날자를 보여줍니다.
2. 다양한 언어를 입력할 수 있습니다.
3. 글꼴 유형, 크기, 색상 및 위치를 설정할 수 있습니다.
4. 날자 형태와 상태바 클릭 동작을 설정할 수 있습니다.
5. 1x1 위젯 지원.


2012년 3월 1일 목요일

Battery Widget

https://play.google.com/store/apps/details?id=com.pjw.batterywidget
https://play.google.com/store/apps/details?id=com.pjw.bwp

배터리 위젯은 상태바에 배터리 잔량과 상태, 온도, 전압, CPU 사용률 등을 표시합니다.

설치된 위젯을 한번 클릭하면 온도와 전압을 보여주며 더블클릭하면 설정화면이 나타납니다.

버그나 원하시는 새로운 기능이 있다면 이메일로 연락 바랍니다.

영어, 프랑스어, 이탈리아어, 한국어 , 폴란드어, 러시아어, 네덜란드어, 스페인어, 중국어 지원.

기능

1. 배터리 충전, 방전, 경고, 위험, 완충 알람.
2. 상태바에 배터리 상태 표시.
3. 원형 그래프 형태의 1x1, 2x2 위젯.
4. 위젯 크기, 색상, 배치를 변경 가능.
5. 온도, 전압, 배터리잔량, 충전상태, 화면상태 그래프.

Plus 버전

6. 추가 상태바 아이콘 지원.
7. 위젯 해상도
8. WiFi, CPU 사용률 그래프.
9. 충전, 방전 남은 예상시간 보여줌.
10. 과열 알람.
11. 충전 완료 알림 레벨 설정.


2012년 2월 22일 수요일

All That Recorder

https://play.google.com/store/apps/details?id=com.pjw.atrl
https://play.google.com/store/apps/details?id=com.pjw.atr

All That Recorder 는 고품질의 음성 녹음 프로그램입니다.
사용이 쉽고 최고의 녹음 품질을 가지고 있으며 MP3 녹음에 최적화되어 있습니다.
녹음 압축률과 품질 설정이 가능하며, 일시 정지, 녹음 모니터링을 지원합니다.
파일 자르기와 계속 녹음 기능을 지원합니다.
어떠한 광고도 출력되지 않으며 불필요한 실행 권한을 요구하지 않습니다.

버그나 원하시는 새로운 기능이 있다면 이메일로 연락 바랍니다.

지원 파일 포맷 : MP3, WAV, OGG, 3GP
지원 언어 : 아랍어, 중국어, 영어, 이탈리아어, 일본어, 한국어, 폴란드어, 포르투갈어, 러시아어, 슬로바키아어, 터키어.

* 통화녹음 전용 프로그램이 아닙니다. 통화녹음을 보증하지 않습니다.
* Lite 버전을 사용할 수 있습니다.
* Lite 버전은 정식 버전의 모든 기능이 있으나, OGG/MP3 녹음은 1분만 가능합니다.

기능

1. 무제한 실시간 녹음
2. 흔들어 녹음
3. 계속 녹음
4. 사운드 모니터링
5. 디지털 필터, AGC(자동 이득 조절), 묵음 제거
6. 구간 반복 재생
7. 재생 속도 조절 & 이퀄라이저 (3GP 제외)
8. wav 파일 변환기
9. 파일 자르기

파일 자르기:
WAV와 MP3 파일의 뒤쪽을 자를 수 있습니다. (재생화면 - 메뉴 - 잘라내기)

계속 녹음:
기존 WAV, MP3 파일에 계속해서 녹음할 수 있습니다. (목록 - 긴 클릭 - 계속 녹음)

흔들어 녹음:
화면을 켠 후 5초 이내로 전화기를 흔들면 녹음을 시작합니다. (설정 - 흔들어 녹음/필터 - 흔들어 녹음 사용)

권한:
전화상태 읽기 권한은 통화중 녹음 일시 정지에 사용됩니다.

위젯:
위젯은 앱을 내부 메모리에 설치 했을 때만 사용할 수 있습니다.
위젯 목록에 위젯이 나오지 않나요? 전화기를 껐다가 켜면 많은 문제가 해결됩니다.

외부 메모리:
킷캣(4.4) 이상에서는 안드로이드에서 외부 메모리 사용을 제한합니다.
외부 메모리를 사용하기 위해서는 다음 과정을 수행하세요.

1. 탐색기 앱 등을 이용해서 외부 메모리에 다음 폴더를 만드세요.
"/storage/extSdCard/Android/data/com.pjw.atr"
외부 메모리 경로(/storage/extSdCard)는 기기마다 다를 수 있습니다.

2. AllThatRecorder의 설정을 변경하세요. (설정-시스템- 작업 경로)
"/storage/extSdCard/Android/data/com.pjw.atr"

* com.pjw.atr : All That Recorder, com.pjw.atrl : All That Recorder Lite


2011년 8월 29일 월요일

Noise Meter

https://play.google.com/store/apps/details?id=com.pjw.noisemeter

소음측정기
안드로이드 기기로 소리 크기를 측정하세요.
사용하기 쉽고 기능이 다양합니다.
데시벨 dB 값을 그래프로 표현해줍니다. 필터 특성 그래프를 볼 수 있습니다.

광고가 없습니다.
불필요한 권한을 요구하지 않습니다.

인앱 카페가 있습니다.
이 프로그램이 유용하시면, 커피 한 잔 사주세요. ^^

기능:
1. 백그라운드에서 측정
2. 평균, LAeq, 최소, 최대, 순간최대 dB값 표시
3. 자료처리시간 설정가능
4. 높은 또는 낮음 알람
5. dB(A), 저역, 고역, 대역 통과 필터
6. 필터 특성 그래프 보기
7. 화면꺼짐방지
8. 로그저장과 로그보기
9. 밝기 측정 (lux)
10. 스펙트럼 분석기능.

이 응용 프로그램은 과학적인 장비 대신 사용될 수 없습니다.

기기에 따라 측정값에 차이가 발생할 수 도 있습니다.

AGC (자동 이득 제어) 채용 장치는 중요한 측정 오류가 발생합니다. 이것은 프로그램의 잘못이 아닙니다.

Noise Sound level meter
dB counter