2024年10月28日月曜日

Show weather reports OLED(SSD1306) with Raspberry Pi

Raspberry Pi Zero W Rev 1.1にinstallしたRaspberry pi OS 12 (bookworm) の動作確認です

OLED(SSD1306)に天気情報を流すPython scriptを書いてみた。


ベースのコードは、Adafruit_CircuitPython_SSD1306 の/examples/ssd1306_pillow_animate.py

# pip install adafruit-circuitpython-ssd1306
# pip install pillow
# git clone https://github.com/adafruit/Adafruit_CircuitPython_SSD1306

fontは、IPAフォントを使用
#apt install fonts-ipaexfont

[p3-ssd1306_pillow_animate_weather-flat-24.py]

#!/usr/bin/env python
# -*- coding:utf-8 -*

# SPDX-FileCopyrightText: 2014 Tony DiCola for Adafruit Industries
# SPDX-License-Identifier: MIT

# This example is for use on (Linux) computers that are using CPython with
# Adafruit Blinka to support CircuitPython libraries. CircuitPython does
# not support PIL/pillow (python imaging library)!

import math
import time
from board import SCL, SDA
import busio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306

#####
import local_weather

def text_get():

   text=local_weather.get_weather()
   return text


#####
text=text_get()

font = ImageFont.truetype("fonts-japanese-gothic.ttf", 24)

# Create the I2C interface.
i2c = busio.I2C(SCL, SDA)

# Create the SSD1306 OLED class.
# The first two parameters are the pixel width and pixel height.
# Change these to the right size for your display!
disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)

# Note you can change the I2C address, or add a reset pin:
# disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, addr=0x3c, reset=reset_pin)

# Get display width and height.
width = disp.width
height = disp.height

# Clear display.
disp.fill(0)
disp.show()

# Create image buffer.
# Make sure to create image with mode '1' for 1-bit color.
image = Image.new("1", (width, height))

# Load default font.
###org## font = ImageFont.load_default()

# Alternatively load a TTF font.  Make sure the .ttf font file is in the
# same directory as this python script!
# Some nice fonts to try: http://www.dafont.com/bitmap.php
# font = ImageFont.truetype('Minecraftia.ttf', 8)

# Create drawing object.
draw = ImageDraw.Draw(image)

# Define text and get total width.
##text = (
##    "SSD1306 ORGANIC LED DISPLAY. THIS IS AN OLD SCHOOL DEMO SCROLLER!!"
##    + "GREETZ TO: LADYADA & THE ADAFRUIT CREW, TRIXTER, FUTURE CREW, AND FARBRAUSCH"
##)
bbox = draw.textbbox((0, 0), text, font=font)
maxwidth = bbox[2] - bbox[0]

# Set animation and sine wave parameters.
amplitude = height / 4
offset = height / 2 - 4
velocity = -2
startpos = width

# Animate text moving in sine wave.
print("Press Ctrl-C to quit.")
pos = startpos
while True:
    # Clear image buffer by drawing a black filled box.
    draw.rectangle((0, 0, width, height), outline=0, fill=0)
    # Enumerate characters and draw them offset vertically based on a sine wave.
    x = pos
    for i, c in enumerate(text):
        # Stop drawing if off the right side of screen.
        if x > width:
            break
        # Calculate width but skip drawing if off the left side of screen.
        if x < -10:
            bbox = draw.textbbox((0, 0), c, font=font)
            char_width, char_height = bbox[2] - bbox[0], bbox[3] - bbox[1]
            x += char_width
            continue
        # Calculate offset from sine wave.
##org        y = offset + math.floor(amplitude * math.sin(x / float(width) * 2.0 * math.pi))
        # Draw text.
##        draw.text((x, y), c, font=font, fill=255)
##      append by pi 2924/9  flat!! fstart
        y=0
##      append by pi 2924/9  end
        draw.text((x, y), c, font=font, fill=255)
        # Increment x position based on chacacter width.
        bbox = draw.textbbox((0, 0), c, font=font)
        char_width, char_height = bbox[2] - bbox[0], bbox[3] - bbox[1]
        x += char_width

    # Draw the image buffer.
    disp.image(image)
    disp.show()

    # Move position for next frame.
    pos += velocity
    # Start over if text has scrolled completely off left side of screen.
    if pos < -maxwidth:
        pos = startpos

    # Pause briefly before drawing next frame.
####    time.sleep(0.001)

[local_weather.py]

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import re
import json
import requests

#import sys
#sys.dont_write_bytecode = True

def get_weather():
#  url = 'http://weather.livedoor.com/forecast/webservice/json/v1'
  url = 'https://weather.tsukumijima.net/api/forecast'
  # 東京のcityタグのid
  payload = {'city': '130010'}
  # お天気情報をjsonで取得
  try:
     data = requests.get(url, params = payload).json()
  except Exception as e:
#     return e
     return '天気情報がありません'


  # 天気情報をedit
  rt=''
  max_len=len(data['forecasts'])
# 今日、明日、(明後日)の情報
  for forecast in data['forecasts']:
     rt+=('{0} ({1}) '.format(forecast['date'], forecast['dateLabel']))
     rt+=(' {} '.format(forecast['telop']))
     if forecast['temperature'].get('max') is not None:
        rt+= ('最高気温 {}℃  '.format(forecast['temperature']['max']['celsius']))
        rt+= ('最高湿度 {}% '.format(forecast['temperature']['max']['fahrenheit']))
     if forecast['temperature'].get('min') is not None:
        rt+= (' 最低気温 {}℃  '.format(forecast['temperature']['min']['celsius']))
        rt+= (' 最低湿度 {}% '.format(forecast['temperature']['min']['fahrenheit']))
     rt += ('{}の天気は、{}でしょう '.format(forecast['dateLabel'], forecast['telop']))

  rt+=('以降が{}の天気概況 '.format(data['location']['city']))
  rt+=(' ' + data['description']['text'])
  rt=re.sub(r'\n|。|、', "", rt)
  return rt

if __name__ == '__main__':
   rt=get_weather()
   print(rt)


2024年9月17日火曜日

Raspberry pi OS 12 (bookworm) で wifi Power Management:on になってる

 Raspberry pi OS 12 (bookworm) のinstall 確認用に、中古のRaspberry Pi Zero W Rev 1.1 を入手して、インストールメディア作成して

power on 起動になかなか時間がかかる、リモートでやっと繋がったと思うとすぐ無反応になる

これは、大昔に経験した事象だったかなと思い、

iwconfig コマンド打つと、Power Management:on だと、

しょうがないので、NetworkManager とか訳のわからんものは使ってないので、潔く、/etc/network/interface に wireless-power off を追加する

再起動で、普通にリモート接続出来るようになりました

Pi Zero Wって標準では、wifiしかないんですがね。不思議なことに 1B plus はドングルのwifiはPower Management:offだったけどね


2024年9月14日土曜日

Raspberry pi OS 12 (bookworm) で NetworkManager を使用しない

Raspberry Pi OS が bookworm の場合は、NetworkManager が標準ですが、

Redhat系で、過去に使いにくさを経験してたので、

古来からの(?) /etc/network/interfaces  の設定に変更しました

1. interfacesファイルの作成

# cat interfaces

#wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf

#iface default inet dhcp

allow-hotplug wlan0

auto wlan0

#iface wlan0 inet dhcp

iface wlan0 inet static

        address 192.168.xxx.yyy

        netmask 255.255.255.0

        gateway 192.168.xxx.yyy

wpa-ssid "xxxx"

wpa-psk "ppppp"

dns-nameservers 192.168.xxx.yyy

iface wlan1 inet static

        address 192.168.xxx.yyy

        netmask 255.255.255.0

        gateway 192.168.xxx.yy

wpa-ssid "xxxxx"

wpa-psk "ppppp"

auto lo

iface lo inet loopback

auto eth0

iface eth0 inet static

        address 192.168.xxx.yyy

        netmask 255.255.255.0

        gateway 192.168.xxx.yy

dns-nameservers 192.168.xxx.yy

2. NetworkManagerの無効化及び停止

   sudo systemctl disable NetworkManager

   sudo systemctl stop NetworkManager

3. resolv.confの手動設定

 # cat resolv.conf

   # Generated by NetworkManager

    nameserver 192.168.xxx.yy

4. reboot

  以上


2024年1月6日土曜日

久々にネジザウルス使う 感動

 ThinkCentre M75q-1 Tiny の

WiFi 5 モジュール(intel Wireless-AC 9260)を交換(ダウングレード)しようとして

見た目ちょっとやばそうな螺子だなと思ったんだが他で実績のあるドライバーで

回すと、どんどんなめていく。。

おまけに、余計なアンテナ端子ガードが付いてて、ネジザウルス使うのに邪魔

そのガードをやっと外して、

さら螺子だったけどネジザウルスでするすると廻った

のに感動です!!







2023年11月30日木曜日

Wifi Card Replacement Lenovo Thinkpad L390 from AC-9560 to Wi-Fi 6E AX210 OK!!

Thinkpad L390ですが、

 ネットで調べても、

CNVi対応の無線LANカードモジュールしか使えないとの情報はあるんですが、

非CNViカード(Eキーだけ、Aキーなし)が使えたとの情報がありませんね。


試してみました。

何の問題も無く使えましたね。

AX対応のルーターに接続出来ました。

リンク速度: 1201(Mbps)     でした。

2023年3月6日月曜日

Sockets not releasing for Pico_W

 https://github.com/micropython/micropython/issues/10812

の方と同様の現象発生で、昨日悩まされてました。

You need to close the waiting (bound on port 80) socket, otherwise you won't be able to make a new one on the same port.

しょうがないので、とりあえず、bind(addr)を正常終了までリトライするコード

に変えてみました。

以下、コード例

....

# Open socket

addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

s = socket.socket()

##s.bind(addr)

bs="addr"

ec=0

while bs!=None:

  try:

    bs=s.bind(addr)

  except OSError:

    ec=ec+1

    print("EADDRINUSE?? " + str(ec))

  utime.sleep(1)

  print('s.bind(addr) rt ', bs)

s.listen(1)

print('listening on', addr)

....

とりあえず、

最悪でも、2分以内に、bind出来た。。


2023年2月22日水曜日

micro:bit V1 でちょっと遊ぶ

 昨年の暮れぐらいからマイコンの整理を始めてました。結局Arduino系は、ブートローダーの最新化で、殆ど動いたので(20台位)、結局塵は減らない。
ごく最近、箱の中で眠っていたmicro:bit V1 を発見!!  
Micropython を最新化してちょっと遊んでみました。今更面白いと思うのはボケて来たせい?!
入時(2017年らしい)は、ちょっと触って、うーん(!?)でお蔵入りでした。
今回、
micro:bit用エッジコネクタピッチ変換基板 など入手して、ちょっと遊んでみました。
(note pc 用の小さいスピーカーを付けられるように)

[サンプルコード]

from microbit import *
import speech
from math import floor
i2c.init(freq=100000, sda=pin20, scl=pin19)
#i2c.scan()
def temp_get():
  o=i2c.read(0x48, 2)
  point=floor(int(o[1]) / 23)
  #print("%s.%s" % (o[0], point))
  temp=("%s.%s") % (o[0], point)
  print (temp)
  return temp
while True:
    temp=temp_get()
    display.show(Image.HEART)
    sleep(1000)
#    display.scroll('Hello')
    display.scroll(temp)
#    speech.say("Konnithiwa")
    speech.say(temp)

LM75温度センサから値を取得して、マトリックスLEDでスクロール
と読み上げ
但し、LM75からの値取得が正しいのか否かは不明です。