pythonのimport imaplibで日本語フォルダ名を使う場合はエンコードが必要

環境

  • PRETTY_NAME=”Ubuntu 22.04.3 LTS”
  • Python 3.10.12
  • pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)

手順

imap_toolsというのが楽らしいのでインストール

pip install imap_tools

インポートして実行

import imap_tools
mailbox_name = "INBOX.ジム.予約"
status, messages = mail.select(imap_tools.imap_utf7.encode(mailbox_name))

何もしない場合のエラー

mail.select(“INBOX.ジム.予約”)

として

yoshitake@mail:~/dovecot_delivery$ python3 test.py 
Traceback (most recent call last):
  File "/home/yoshitake/dovecot_delivery/test.py", line 15, in <module>
    mail.select("INBOX.ジム.予約")
  File "/usr/lib/python3.10/imaplib.py", line 756, in select
    typ, dat = self._simple_command(name, mailbox)
  File "/usr/lib/python3.10/imaplib.py", line 1230, in _simple_command
    return self._command_complete(name, self._command(name, *args))
  File "/usr/lib/python3.10/imaplib.py", line 987, in _command
    arg = bytes(arg, self._encoding)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 6-7: ordinal not in range(128)

ソース全体

import imaplib
import imap_tools
from email.header import decode_header

# IMAPサーバの設定
mail_server = 'mail.huga.co.jp'
username = 'hoge'
password = 'hugahuga'

# IMAPサーバに接続
mail = imaplib.IMAP4_SSL(mail_server)
mail.login(username, password)

# # メールボックスを選択
mailbox_name = "INBOX.ジム.予約"
status, messages = mail.select(imap_tools.imap_utf7.encode(mailbox_name))

# # メール検索(例: 未読メール)
status, messages = mail.search(None, "(UNSEEN)")
unread_count = len(messages[0].split())
print(f"未読メールの件数: {unread_count}")

# 接続を閉じる
mail.close()
mail.logout()

ロシェ桃山年末年始の営業時間

年末年始は30まで通常営業。

1/31日は18:00閉店 1/1 休業 1/2-4 は事前電話予約ある時間営業となります

12/27 14:30-23:00
12/28 14:30-23:00
12/29 14:30-23:00 
12/30 10:00-23:00 
12/31 10:00-18:00 
1/1 休業 
1/2 要電話予約(10:00-23:00) 
1/3 要電話予約(10:00-23:00) 
1/4 要電話予約(10:00-23:00)

picoprobeの環境構築で手間取ったのでメモ

Interface7月号のラズパイPicoでゼロから作るOSを試そうとしたら環境構築で手間取ったのでメモ。

先に結論

Interface記載の各ダウンロード先最新のもので環境構築をするとpicoprobeのデバックが動かない。対処としてxpmで入れたopenocdを使用すると動いた。

インストール方法

node/npm/xpmが入っている環境で

cd my-project
xpm init # Only at first use.

xpm install @xpack-dev-tools/openocd@latest --verbose

事象

手順通りだとエラー。エラーメッセージを取り損ねているけどlocalhost:3333がtimeoutとかの類だったはず。

cmsis-dap.cfgを修正しadapter speed 5000を追記するという手順をしても以下エラー。

Error: Sequence 4 not supported. 
Info : DAP init failed


Error: Sequence 3 not supported.
Error: Sequence 4 not supported.

原因

Interface記載のopenocdだと今のpicoprobeの処理に対応していない。こちらのリンク先のパッチが未適用。(公式だと取り込まれていた。)Interface記載の段階では動いたようなのでおそらくpicoprobeのバージョンアップで動作が変わったと思う。(が、picoprobe側の変更履歴は確認していない。)

各バージョン

多分直接関係するのはopenocdとpicoprobeだけだと思う

C:\Users\kitam>node -v
v18.17.1

C:\Users\kitam>npm -v
9.6.7

C:\Users\kitam>xpm --version
0.16.3
picoprobe-cmsis-v1.0.3
  "xpack": {
    "minimumXpmRequired": "0.16.3",
    "dependencies": {},
    "devDependencies": {
      "@xpack-dev-tools/arm-none-eabi-gcc": {
        "specifier": "12.3.1-1.1.1",
        "local": "link",
        "platforms": "all"
      },
      "@xpack-dev-tools/windows-build-tools": {
        "specifier": "4.4.0-1.1",
        "local": "link",
        "platforms": "all"
      },
      "@xpack-dev-tools/openocd": {
        "specifier": "0.12.0-2.1",
        "local": "link",
        "platforms": "all"
      }
    },
Eclipse IDE for Embedded C/C++ Developers (includes Incubating components)

Version: 2023-06 (4.28.0)
Build id: 20230608-1333

CH32V003とWCH-LinkEでLチカ

秋月で販売開始になったCH32V003J4M6(マイコン本体)とWCH-LinkEエミュレーター(書き込み/デバック装置)で書き込みができたのでそこまでのメモ。

基本的にはこちらの記事をトレースしてわからなかったことを追記した感じ

必要だったのもの

ハード

  • CH32V003J4M6 1個
  • WCH-LinkEエミュレーター 1個
  • ピッチ変換基盤 1個(これの同等品)
  • LED 1個(3mm使った)
  • 抵抗 1個(1 KΩ 大体で)
  • ブレッドボード 1個
  • コンデンサ 0.1uF 1個
  • ジャンパーケーブル 5本ぐらい
  • 書き込み用PC Windows11(1台)

ソフト

元記事と違った箇所、または追加したとこ

「いつも通り Workspace の場所を決めて Launch をクリックします。」は出なかった。後で選べる。

File⇒Open Procets from File System をクリックします。」は「Open Procets from File System」のとこが微妙に名前変わっていた

「コンパイル」のトンカチアイコンは見当たらず、ビルドアイコンがツールバーの左寄りにあった。ダウンロードアイコンもツールバーの左寄り。

サンプルソースはGPIO_Pin_0でLチカしているけどSOP8のだとPD0は出ていないのでGPIO_Pin_6(PD6の1番ピン)に変更

書き込みのたびに、MounRiver Studioにて以下操作

  1. メニューバーからFlash選択
  2. configration選択
  3. target modeにあるqueryボタンクリック
  4. プルダウンに出てくるWCH-LinkRV選択
  5. 少し下のErase Code FlashでBy power off を選択してApplyクリック

接続

PCのUSBにPCのUSBにWCH-LinkEエミュレーター接続

WCH-LinkEエミュレーターCH32V003
GND2番ピン(VSS)
3V34番ピン(VDD)
SWDIZO8番ピン()

CH32V003の1番ピン – Lチカ用のLED – 1KΩ抵抗 – CH32V003の2番ピン(VSS)

CH32V003の2番ピン(VSS) – 0.1uFコンデンサ – CH32V003の4番ピン(VDD)

ソース

ほぼそのままだけど下の

/********************************** (C) COPYRIGHT *******************************
 * File Name          : main.c
 * Author             : WCH
 * Version            : V1.0.0
 * Date               : 2022/08/08
 * Description        : Main program body.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for 
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/

/*
 *@Note
 GPIO routine:
 PD0 push-pull output.

*/

#include "debug.h"

/* Global define */

/* Global Variable */

/*********************************************************************
 * @fn      GPIO_Toggle_INIT
 *
 * @brief   Initializes GPIOA.0
 *
 * @return  none
 */
void GPIO_Toggle_INIT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
}

/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void)
{
    u8 i = 0;

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    Delay_Init();
    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n", SystemCoreClock);

    printf("GPIO Toggle TEST\r\n");
    GPIO_Toggle_INIT();

    while(1)
    {
        Delay_Ms(250);
        GPIO_WriteBit(GPIOD, GPIO_Pin_6, (i == 0) ? (i = Bit_SET) : (i = Bit_RESET));
    }
}

Aliで買ったLEDシリコンチューブ届いた

ここのやつ。

5mのオレンジで12Vで約1.2A。

明るさとしては室内の照明だと十分目立つけど昼の屋外だとほぼわからないぐらい。屋外で使うならやや日が傾きだしたぐらいからかな。晴れた6月の京都で18時ぐらいで見えるぐらい。

なお開封直後はゴム臭がけっこうした。

チューブに黒い点がついていてそこから切り離せるはずだけど試していない。

看板に使用したいので曲げてみた。折り目はつかないのでターンのきついところでは接着剤等で角度保持してやらなくてはならない。

ちなみに看板は最初トリマーで掘り込もうと思ったけど丁寧にやるのは時間がかかるのであきらめた。大きいCNCがあったら楽そうだけどCNC事態を持っていないのでレーザーカッターでアクリルを切り抜いたやつで作る予定。

サーボモーターSG90が半分の角度しか回らないので調査

環境

  • VSCode
  • PlatformIO
  • ESP-WROOM-02(自作基盤)
  • SG90(のAliexpressで買った互換品?)
  • Windows11

事象

SG90をPlatformIOで入れたライブラリで0,90,180度で動かそうとしたところそれぞれ0,45,90度ぐらいしか動かなかった

ソースは以下

#include <Arduino.h>
#include <Servo.h>


#define SERVO_PIN   12


Servo servoMotor; 

void setup() {
  Serial.begin(115200);
  delay(100);
  digitalWrite(LED_PIN, HIGH);
  servoMotor.attach(SERVO_PIN);
}

int count = 0;
int angle[] = {0,90,180};
void loop() {
  
  servoMotor.write(angle[count%3]);

  Serial.printf("%s - run %d %d \n",__func__,count,servoMotor.readMicroseconds());
  count++;
  delay(1000);
}
[env:esp_wroom_02]
platform = espressif8266
board = esp_wroom_02
framework = arduino
monitor_speed = 115200
upload_port = COM9

servoMotor.readMicroseconds()でみてみると本来500,1450,2400(ms)ぐらいであってほしい数値が1000,1500,2000ぐらいになっていた。

対応

サーボモーターの初期化をするときに以下のように明示的に0度と180度(データシート的には-90度と90度)の値を指定してやったら動いた。

servoMotor.attach(SERVO_PIN,500,2400);

原因

PlatformIOだとplatform を切り替えるとそれぞれのマイコンに応じたライブラリが読み込まれるみたい。そしてそこ(Servo.h)にあるデフォルト値が欲しい値じゃなかった

#define DEFAULT_MIN_PULSE_WIDTH      1000 // uncalibrated default, the shortest duty cycle sent to a servo
#define DEFAULT_MAX_PULSE_WIDTH      2000 // uncalibrated default, the longest duty cycle sent to a servo 
#define DEFAULT_NEUTRAL_PULSE_WIDTH  1500 // default duty cycle when servo is attached

読み込まれているライブラリはPIOホーム -> Libraries -> Built-inから(必要なら検索で絞って)Servoを選んでRevealを押すと確認可能。

ロシェ桃山年末年始予定

12/29-1/3は予約が必要です。

12/26 通常営業(18:00-23:00)

12/27 通常営業(14:30-23:00)

12/28 通常営業(14:30-23:00)

12/29 1時間程度前まで予約必要で終日営業(10:00-23:00)

12/30 前日まで予約必要で終日営業(10:00-23:00)

12/31 前日まで予約必要で短縮営業(10:00-19:00)

1/1 前日まで予約必要で短縮営業(13:00-22:00)

1/2 前日まで予約必要で短縮営業(11:00-22:00)

1/3 前日まで予約必要で終日営業(10:00-23:00)

1/4 通常営業再開(14:30-23:00)

連絡先 090-3524-7416  または 075-632-8978

携帯の方がつながりやすいと思います

ZH02を触ってみた

先日入手したWinsenのダストセンサーZH06を触ってみた。先日ZPH02というのを触ったけどそれより少し良い奴。ZPHはDuty比しか返してくれないので換算が面倒だけどこっちはI2Cでug/m3で返してくれる。ただしPWMは二つの値を順次返してくれるようでマイコンなしで扱うのは大変そう。

コネクタはオスオスのがついてきた。メスのコネクターはなかったので半分に切ってピンヘッダーに半田した。

UART接続

環境

  • ArduinoNano互換機
  • Arduino IDE1.8.13(Windows10)
  • ブレッドボードとジャンパーケーブル少々

配線

NanoとPCはUSB接続

ZH06Nano
#1 VDD5V
#2 GNDGND
#3 Reserved未接続
#4 RXD Serial receive pinD3(スケッチで指定)
#5 TXD Serial send pinD2(スケッチで指定)
#6 Reserved未接続
#7 Reserved未接続
#8 PWM output未接続

ソース

#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 2);

#define LED_PIN 13

#define BUFFER_SIZE 31
#define START_BIT 0x42

unsigned char inBuffer[BUFFER_SIZE];


void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  mySerial.setTimeout(1500);
}

void loop() {
  bool readFlg = false;
  int bufIndx = 0;

  if(mySerial.find(START_BIT)){
    mySerial.readBytes(inBuffer,BUFFER_SIZE);
  }

  if (checkSum()) {
    writeData();
  }
  delay(100);
}

bool checkSum() {
  int dataSum = 0;
  for ( int i = 0; i < (BUFFER_SIZE-2) ; i++) {
    dataSum += inBuffer[i];
  }
  dataSum += START_BIT;
  
  Serial.print("calc=");
  Serial.print(dataSum, HEX);
  Serial.print(" checksum=");
  Serial.print( (inBuffer[29] << 8) + inBuffer[30], HEX);
  Serial.print(" ");

  bool isGoodChecksum = (dataSum == ((inBuffer[29] << 8) + inBuffer[30]));

  
  if(!isGoodChecksum){
    Serial.println("チェックサムエラー");
  }
  return isGoodChecksum;
}

void writeData() {
  for ( int i = 0; i < BUFFER_SIZE; i++ ) {
    Serial.print(inBuffer[i], HEX);
    Serial.print(",");
  }
  Serial.print("[pm1.0 ");
  Serial.print((inBuffer[9] << 8) + inBuffer[10]);
  Serial.print("]");
  Serial.print("[pm2.5 ");
  Serial.print((inBuffer[11] << 8) + inBuffer[12]);
  Serial.print("]");
  Serial.print("[pm10 ");
  Serial.print((inBuffer[13] << 8) + inBuffer[14]);
  Serial.print("]");
  Serial.println("");
}

問い合わせモードにするコマンドもあるけど試していない。データシートのリンクないけどこれで動いた

ZPH02を触ってみた

先日入手したWinsenのダストセンサーZPH02を触ってみた。検索でv1.2のデータシートがかかったけど公式からデータシートにリンクが張られているV1.0のほうだった。(公式の写真だとピンヘッダーが1*4だけど1*5のが届いたので微妙に違うものかも)なお、ピンヘッダーについてはデータシートにアサイン等記載なかった。少なくともコネクタと並び順は違う。

コネクタ(EH2.54-5P terminal socket)に関してはケーブルが付属していなかった。とりあえずジャンパーのメスと同じサイズなのでそれで引きさした。

出力は粒子数直接ではなくて粒子数に応じて出力LowのDuty比がかわる。データシート参照。

UART接続

環境

  • ArduinoNano互換機
  • Arduino IDE1.8.13(Windows10)
  • ブレッドボードとジャンパーケーブル少々

配線

NanoとPCはUSB接続

PHZ02Nano
#1 Control pinGND
#2 Output OUT2/RXD未接続
#3 Power positive (VCC)5V
#4 Output OUT1/TXDD2(スケッチで指定)
#5 GNDGND

#1をGNDにするか未接続かでPHZ02の出力がUARTになるかPWMになるかが切り替えられる。GNDだとUARTモードになる。UARTだと#4がTXになるのでそれをNanoのRXを割り当てたGPIOで受け取る。もともとのハードウェアなRX端子はPCとのやりとりで使いたいのでSoftwareSerialにて割り当てた。

ソース

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);

#define LED_PIN 13

#define BUFFER_SIZE 9
unsigned char inBuffer[BUFFER_SIZE];


void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
}

void loop() {
  bool readFlg = false;
  int bufIndx = 0;
  
  while (mySerial.available() > 0) {
    unsigned char readValue =  mySerial.read();
    if (bufIndx > BUFFER_SIZE) {
      continue;
    }
    inBuffer[bufIndx] = readValue;
    bufIndx++;

    readFlg = true;
  }

  delay(10); // 少し待ってあげないと配列がちゃんと読み込めない

  if (readFlg && checkSum()) {
    writeData();
  }
  delay(100);
}

bool checkSum() {
  unsigned char tempq = 0;
  for ( int i = 1; i < 8 ; i++) {
    tempq += inBuffer[i];
  }
  tempq = (~tempq) + 1;
  
  if(!(tempq == inBuffer[8] )){
    Serial.println("チェックサムエラー");
  }
  return (tempq == inBuffer[8] );
}

void writeData() {
  for ( int i = 0; i < BUFFER_SIZE; i++ ) {
    Serial.print(inBuffer[i], HEX);
    Serial.print(",");
  }
  Serial.print("[");
  Serial.print(inBuffer[3]);
  Serial.print(".");
  Serial.print(inBuffer[4]);
  Serial.print("]");

  Serial.println("");
}


ZPH02の通信速度(Baud Rate)は9600なのでソフトシリアルで指定。コンストラクタでD2を指定。

コメント入れてあるdelay(10)がないと配列ちゃんと読み込めなかった。

チェックサムは~7バイト。スタートバイトはいらない。

for ( int i = 1; i < 8 ; i++) {

なにか、チェックサムがおかしな値しか返らなくなって再起動しなくてはいけない事象があった。(まだ詳しく見られていない。)

精度はパルス幅0.1%までの模様。値は結構上下するみたいなのでそのまま使うと上下に振れすぎて読みにくいかも。

スタートビットちゃんとみてデータ取得していない拾っていない途中まで読み込んでいるのは次回捨てている。

PWM接続

環境

  • ArduinoNano互換機(電源用)
  • Arduino IDE1.8.13(Windows10)
  • ブレッドボードとジャンパーケーブル少々

配線

PHZ02Nano
#1 Control pin未接続
#2 Output OUT2/RXDPWM出力(計測用にオシロの+に)
#3 Power positive (VCC)5V
#4 Output OUT1/TXD未接続
#5 GNDGND(計測用にオシロの-に)

#1をGNDにするか未接続かでPHZ02の出力がUARTになるかPWMになるかが切り替えられる。未接続だとPWMモードになる。

出力

1秒サイクルでLow(0V)の割合が濃度。