Tamesuke-Goto Maker的Blog -7ページ目

Tamesuke-Goto Maker的Blog

地域ISP管理者だけれど、ここ3年ほどMakerなJobが増えたのでまとめてみたいと思います 旧ハンドル Ringoro

以前書いた Lチカ回路 を元に基板化してみました。
 
ATTiny13, 85など 8pinのAVRチップを想定してLEDは使えるだけ5系列ドライブできる様にしました。
 
{B5124A6B-8213-4C52-B9AB-7FE2C87DACB0}
 
 
今回はPCBGOGO へ PCBGOGOはKiCadのガーバー出力を拡張子変えずにそのままアーカイブして処理してくれるので楽で良いのですよね。
 
{90EDDEE8-7639-44E8-BD8A-6DC8889C48B8}
 
10枚もあれば十分なのだけど、10枚で2200円くらい50枚で3200円くらいだったので50枚オーダーしました。51枚届きました。
 
{BE599F8F-EE54-4874-916F-4E60F8ABEC11}
基板のサイズ、枚数によると思いますが、面付けすると上下左右にダミーエリアを設ける必要があるのであまり効率よくない様な気が。。。素直にそのままオーダした方が安価になる感じもありますね。
 
 
 
 
{98229F42-D30F-47D6-A757-215471607FD8}

スケッチはまた少し変えて、LED4系列をおおよそ1秒おきに乱数で点滅、1系列をアナログ(PWM)でローソクぽくゆらゆら点滅する様なスケッチにしています。

 

乱数の関数は以前ネットのどこかにUPされていたコードで、どこからか覚えてないのですが、short int の乱数を発生してくれる関数です。

 

 

/*

     Blink and Candle Light 

     for  ATTiny13 LED Board 

 

     2017/12/5

 

   PCINT5/A0/D5/RST |1---O---8| VCC

       PCINT3/A3/D3 |2       7| D2/A1/INT0/PCINT2

       PCINT4/A2/D4 |3       6| D1/PWM/PCINT1

                GND |4-------5| D0/PWM/A0/PCINT0

 

   RST = ADC0/PCINT5

 

  PIN5(LED3) Candle Light

 

 */

 

//#include <avr/pgmspace.h> 

 

#define LED1 3

#define LED2 4

#define LED3 0

#define LED4 1

#define LED5 2

 

/*

 *    Random 

 */

 

unsigned int randshort(unsigned int init)

{

  static unsigned int seed;

  if(init!=0){

  seed ^= init;

  }

  seed *= 52341;

  seed += 37;

  return(seed ^ 0x1234);

}

 

void setup() {

  randshort(analogRead(0));

  pinMode(LED1, OUTPUT);

  pinMode(LED2, OUTPUT);

  pinMode(LED3, OUTPUT);

  pinMode(LED4, OUTPUT);

  pinMode(LED5, OUTPUT);

 

 

 

void loop() {

  static unsigned char d;

  static unsigned char t;

  d = randshort(0);

  analogWrite(LED3,d);  

  if(t++ > 11){

    t=0;

    digitalWrite(LED1,(d & 0x11));

    digitalWrite(LED2,(d & 0x28));

    digitalWrite(LED4,(d & 0x44));

    digitalWrite(LED5,(d & 0x82));

  }

  delay(80);

}

 

  

 
 電源電圧はLED20個並列、乾電池3個4.5Vのつもりで作りましたがLEDの数を減らしたりすれば3Vでも十分明るい様です。

 
以前 ESP-WROOM-02 で使った温度センサ HDC1000 は秋月からはディスコンの様なので、新タイプのSHT31を入手して使ってみる事にします。
 
秋月のページはこちら SHT31 
 
 
 
{EA3570D2-F681-483F-B6D9-D4004C445FA7}
 
秋月のモジュールは HDC1000と同じくRaspberryPiのピン配置に合わせて配線してありますので、そのまま挿す事ができます。
 
Arduino用のサンプルコードが用意されております。 Arduino Sample ライブラリ(zip)
 
このライブラリのサンプルスケッチへ、
#include <ESP8266WiFi.h>
を追加しただけで何の変更もなく動作しました。
 
 
{2CF731D4-AB9E-459A-8517-222A77885E97}
 
前回のスケッチへ少し変更を加え、 wifiでntpから時刻を取得し、スイッチサイエンスのmini LCD で温度・湿度を表示させる様にしてみました。
 
/*
 *   WROOM-02 TEST
 *   
 *   WiFi
 *   NTP Sync
 *   mini LCD
 *   SHT31 module
 *
 */

#include <AE_SHT31.h>
#include <time.h>
#include <Wire.h>
#include <ESP8266WiFi.h>

//Access Point Setting
const char *ssid = "********";
const char *pass = "********";

#define LED_PIN 13

#define lcdaddr 0x3e  // LCD Address
byte contrast = 33;  // コントラスト(0~63)

AE_SHT31 SHT31 = AE_SHT31(0x45);

#define JST  3600*9

IPAddress myIP;

void setup() {
  int t=0;
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(9600);

  Wire.begin();
 
  lcd_cmd(0b00111000); // function set
  lcd_cmd(0b00111001); // function set
  lcd_cmd(0b00000100); // EntryModeSet
  lcd_cmd(0b00010100); // interval osc
  lcd_cmd(0b01110000 | (contrast & 0xF)); // contrast Low
  lcd_cmd(0b01011100 | ((contrast >> 4) & 0x3)); // contast High/icon/power
  lcd_cmd(0b01101100); // follower control
  delay(200);
  lcd_cmd(0b00111000); // function set
  lcd_cmd(0b00001100); // Display On
  lcd_cmd(0b00000001); // Clear Display
  delay(2);

//  WIFI

 WiFi.begin(ssid, pass);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if(t++>20){
      Serial.println("ERROR Wifi CONNECT");
      break;
    }
  }
 
  Serial.println("");
 
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  myIP=WiFi.localIP();
  Serial.println(myIP);
  configTime( JST, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp");

  // SH31
  SHT31.SoftReset();
  // 内蔵ヒーター 0:OFF 1:ON
  SHT31.Heater(0);
 

}

/*
 * Get or Set Info
 */

void getinfo()
{
  Serial.print("ESSID :");
  Serial.println(ssid);

  Serial.print("IP address: ");
  myIP=WiFi.localIP();
  Serial.println(myIP);

}

void setinfo()
{
 
}

int count=0;

void loop() {
  char str1[10];
  char str2[10];
  char stemp[10];
  char shumid[10];
  time_t t;
  struct tm *tm;
 
  int c;
  if(Serial.available()){
     c = Serial.read();
     switch(c){
      case 'g':getinfo();
        break;
      case 's':setinfo();     
      }
  }
  else if (count++==200){

  digitalWrite(LED_PIN,digitalRead(LED_PIN)^1);

   t= time(NULL);
   tm = localtime(&t);

   sprintf(str1,"%02d/%02d   ", tm->tm_mon+1, tm->tm_mday);
   sprintf(str2,"%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);

   lcd_setCursor(0, 0);
   lcd_printStr(str1);
   lcd_setCursor(0, 1);
   lcd_printStr(str2);

  } else if(count==400){

   digitalWrite(LED_PIN,digitalRead(LED_PIN)^1);

   SHT31.GetTempHum();

    dtostrf(SHT31.Temperature(),3,1,stemp);
    dtostrf(SHT31.Humidity(),3,1,shumid);
    sprintf(str1,"%s 'C ",stemp);
    sprintf(str2,"%s %%   ",shumid);

   lcd_setCursor(0, 0);
   lcd_printStr(str1);
   lcd_setCursor(0, 1);
   lcd_printStr(str2);
   count=0;
  }

  delay(10);

}


 
void lcd_cmd(byte x) {
  Wire.beginTransmission(lcdaddr);
  Wire.write(0b00000000); // CO = 0,RS = 0
  Wire.write(x);
  Wire.endTransmission();
}
 
void lcd_contdata(byte x) {
  Wire.write(0b11000000); // CO = 1, RS = 1
  Wire.write(x);
}
 
void lcd_lastdata(byte x) {
  Wire.write(0b01000000); // CO = 0, RS = 1
  Wire.write(x);
}
 
// 文字の表示
void lcd_printStr(const char *s) {
  Wire.beginTransmission(lcdaddr);
  while (*s) {
    if (*(s + 1)) {
      lcd_contdata(*s);
    } else {
      lcd_lastdata(*s);
    }
    s++;
  }
  Wire.endTransmission();
}
 
// 表示位置の指定
void lcd_setCursor(byte x, byte y) {
  lcd_cmd(0x80 | (y * 0x40 + x));
}


==========
 

 

 

 

 
{329DEFE5-E27C-46BC-957E-B52FAE8DA0B0}

 
こいつも大分前に買っておいたのですが3.3V対応のUSBシリアルケーブルが必要だったり、普通のブレッドボードでは配線がやりにくいとかだったりで、しばらく放っておいておりました。せっかくなので遅れてますが秋月の幅広ブレッドボードと3.3V対応USBシリアル変換モジュールを入手し使ってみる事にします。
 
購入したのがスイッチサイエンスの単体モジュールなので、GPIOを何本かプルアップしたりグランドに落としたりしないといけません。結構面倒ですね。
とりあえずLチカするだけでこんな配線になってしまいます。さらに単体稼動するためにはまたジャンパを付け替えるとか、、、
 
これはやっておられん。。。
 
 
{2C33A9EB-1B7F-401B-B2A7-AF744C3D8940}
 
なので、まじめに冶具を作りましょう。基板は秋月のBサイズがよろしいかな。
 
{CACED2C1-9C3F-4D39-9E2E-AD870DC812EC}
 
細ピンヘッダなので丸ピンソケットがよいです。
 
 
{75B6510C-1098-4338-892A-DE50DD3C4E0F}
 
起動リセットSWとライトモードSW 2つでモード切替します。
配線についてはネットに情報がたくさんありますね。以下を参考に致しました。
 

https://qiita.com/ikesato/items/92f4cb143e7aeb5e0f9b

 

i2cの接続は

 

GPIO4 - SDA

GPIO5 - SCL

 

とします。サイトによってはSCLをGPIO14にしている場合もある様ですが、Arduino IDEのデフォルトはGPIO4,5 の様です、

 

冶具として使うので基板上にi2c、SPI、使用可能なGPIOへ簡単に外付け出来る様ピン・ソケットをを半田付けしておきます。i2cピンの並びはRaspeberryPiと同じ配列にしました。これでRaspi用のブレークアウトがそのまま挿入できます。
これでNanoPiで使ったHDC1000モジュールが使えます。
 
 
{CA451DB2-586B-4F25-8423-C1C82EC2CAE3}
 
きれいにまとまった。まだ余裕があるのでいろいろ追加できそう。
 
Lチカだけでは芸がないので Wifiのアクセスポイントに接続してntpサーバから時間を取得、約一秒おきに温度・湿度を表示というスケッチを書いてみました。
 
スケッチはこちらサイトを参考にさせて頂きました ->  http://shirotsuku.sakura.ne.jp/blog/?p=812

 

------------------------

 

/*
 *   WROOM TEST
 *   
 *   NTP Time Sync
 *   HDC1000 i2c
 *
*/

#include <Wire.h>
 
#include <Arduino.h>
#include <time.h>
#include <ESP8266WiFi.h>
//#include <WiFiUDP.h>

//Access Point Setting
const char *ssid = "****";
const char *pass = "****";

#define addr 0x40

#define LED 13
#define JST  3600*9

IPAddress myIP;

void HDC1000_ini(void){
  delay(100);
  Wire.beginTransmission(addr);
  Wire.write(0x02);   //Configuration address
  Wire.write(0x10);   //MODE=1, 14bit
  Wire.write(0x00);
  Wire.endTransmission();  
}

void setup() {
  int t=0;
  pinMode(LED, OUTPUT);
  Serial.begin(9600);

  WiFi.begin(ssid, pass);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if(t++>20){
      Serial.println("ERROR Wifi CONNECT");
      break;
    }
  }
 
  Serial.println("");
 
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  myIP=WiFi.localIP();
  Serial.println(myIP);
  configTime( JST, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp");

  Wire.begin();  
  HDC1000_ini();
 
}

void loop() {
  static short intvl=0;
  time_t t;
  struct tm *tm;

  delay(100);
 
  if(intvl++ & 7 ){
    return;
  }

  digitalWrite(LED, HIGH);   

  t= time(NULL);
  tm = localtime(&t);
   Serial.printf(" %04d/%02d/%02d %02d:%02d:%02d , ",
        tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
        tm->tm_hour, tm->tm_min, tm->tm_sec);

  HDC1000_read();
  digitalWrite(LED, LOW);    

}

void HDC1000_read(void){
  unsigned int temp = 0;
  unsigned int humid = 0;
   
    delay(100);
    Wire.beginTransmission(addr);
    Wire.write(0x00);   //レジスタ0x00
    Wire.endTransmission();
    delay(50);
   
    Wire.requestFrom(addr, 4);
    if(4 <= Wire.available())   
    {       
      temp = (Wire.read()<<8);
      temp += Wire.read();
      humid = (Wire.read()<<8);
      humid += Wire.read();
      Serial.print(temp/65536.0*165.0-40.0);   
      Serial.print(",");
      Serial.println(humid/65536.0*100.0);
    }

}

 

 

実行結果: