0

Adafruit PiOLED - 128x32 Monochrome OLED Showing data scrabb
Moderators: adafruit_support_bill, adafruit

Forum rules
Talk about Adafruit Raspberry Pi® accessories! Please do not ask for Linux support, this is for Adafruit products only! For Raspberry Pi help please visit: http://www.raspberrypi.org/phpBB3/
Please be positive and constructive with your questions and comments.

Adafruit PiOLED - 128x32 Monochrome OLED Showing data scrabb

by stirucherai on Sun Sep 26, 2021 11:49 am

Hi,

Using OLED to show the my lithium battery SOC, Voltage and Current. The display is refreshed ever 1 min. The data are scrabbled after sometime. Added to clear with fill(0)

Code: Select all | TOGGLE FULL SIZE
             disp.fill(0)
             disp.show()
             draw.text((x, top + 0), str("{:6.2f}".format(soc)) +"% : " + str("{:6.2f}".format(voltage)) +"V" , font=font, fill=255)
             draw.text((x, top + 17),str("{:8.2f}".format(current)) + "A" , font=font, fill=255)

             # Display image.
             disp.image(image)
             disp.show()


PiOLED.jpeg
Image which show scrabbled data
PiOLED.jpeg (75.08 KiB) Viewed 58 times


Thanks and Regards
Sarang

stirucherai
 
Posts: 23
Joined: Sun Sep 26, 2021 11:44 am

Re: Adafruit PiOLED - 128x32 Monochrome OLED Showing data sc

by stirucherai on Sun Sep 26, 2021 1:21 pm

Just FYI -- i got 2 of these and both show scrabbled after some time (in 3 to 4 mins it starts showing scarabbled data)

stirucherai
 
Posts: 23
Joined: Sun Sep 26, 2021 11:44 am

Re: Adafruit PiOLED - 128x32 Monochrome OLED Showing data sc

by stirucherai on Mon Sep 27, 2021 12:51 pm

font = ImageFont.load_default()

I am using default font. As i mentioned earlier there 1 min refresh period

stirucherai
 
Posts: 23
Joined: Sun Sep 26, 2021 11:44 am

Re: Adafruit PiOLED - 128x32 Monochrome OLED Showing data sc

by adafruit_support_carter on Mon Sep 27, 2021 3:59 pm

Can you post full code listing.

adafruit_support_carter
 
Posts: 21391
Joined: Tue Nov 29, 2016 2:45 pm

Re: Adafruit PiOLED - 128x32 Monochrome OLED Showing data sc

by stirucherai on Mon Sep 27, 2021 4:07 pm

Code: Select all | TOGGLE FULL SIZE
from bluepy import btle
from bluepy.btle import Scanner, DefaultDelegate
from bluepy.btle import AssignedNumbers
from bluepy.btle import BTLEDisconnectError
from datetime import datetime
from struct import unpack
from log4python.Log4python import log
from oauth2client.service_account import ServiceAccountCredentials
import gspread
import binascii
import threading
import time
import subprocess
###
from board import SCL, SDA
import busio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306
###

BDLLog = log("BDLLog");
RAWLog = log("RAWLog");
next_row=1
timerFlag=0

# 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)

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

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

# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)

# Draw a black filled box to clear the image.
draw.rectangle((0, 0, width, height), outline=0, fill=0)

# Draw some shapes.
# First define some constants to allow easy resizing of shapes.
padding = -2
top = padding
bottom = height - padding
# Move left to right keeping track of the current x position for drawing shapes.
x = 0


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

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



def write2Google():
    global next_row
    global voltage
    global soc
    global current
    global timerFlag
    next_row=next_row+1
    new_row = [datetime.now().strftime("%d/%m/%Y %H:%M:%S"), str("{:6.2f}".format(voltage)), str("{:6.2f}".format(soc)), str("{:8.2f}".format(current))]
    BDLLog.debug("Writing into google sheet")
    BDLLogsheet.resize(next_row)
    BDLLogsheet.append_row(new_row)
    mobileAppSheet.update('B2', datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
    mobileAppSheet.update('C2', str("{:6.2f}".format(soc)))
    mobileAppSheet.update('D2', str("{:6.2f}".format(voltage)))
    mobileAppSheet.update('E2', str("{:6.2f}".format(current)))
    timerFlag=0

def next_available_row(worksheet):
    str_list = list(filter(None, worksheet.col_values(1)))
    return str(len(str_list)+1)


class ScanDelegate(DefaultDelegate):
    def __init__(self):
        DefaultDelegate.__init__(self)
        # ... initialise here

class MyDelegate(btle.DefaultDelegate):
    def __init__(self):
        btle.DefaultDelegate.__init__(self)
        # ... initialise here

    def handleNotification(self, cHandle, data):
        RAWLog.debug(data)
        global voltage
        global soc
        global current
        global timerFlag
        if len(data) >= 85:
          voltage=byte2int(data,25)/1000
          soc=byte2short(data,41)*.4
          current=byte2short(data,29)/100
          voltageMV=round(voltage*100).to_bytes(2, 'little',  signed=True)
          currentMA=round(current*10).to_bytes(2, 'little',  signed=True)
          factCap=byte2short(data,43)/10
          rateCap=byte2short(data,45)/10
          cell1Volt=byte2int(data,47)/1000
          cell2Volt=byte2int(data,49)/1000
          #print(str("{:6.2f}".format(voltage))+ " : " +  str("{:6.2f}".format(soc)) + " : " + str("{:8.2f}".format(current)))
          BDLLog.debug(           str("{:6.2f}".format(voltage)) \
                        + " : " + str("{:6.2f}".format(soc)) \
                        + " : " + str("{:8.2f}".format(current)) \
                        + " : " + str("{:8.2f}".format(factCap)) \
                        + " : " + str("{:8.2f}".format(rateCap)) \
                        + " : " + str("{:8.2f}".format(cell1Volt)) \
                        + " : " + str("{:8.2f}".format(cell2Volt)) \
                        + " : " + str((voltageMV+currentMA).hex()) \
                      )

          if timerFlag == 0:
             draw.text((x, top + 0), "SOC : " + str("{:8.2f}".format(soc)) +"%"     , font=font, fill=255)
             draw.text((x, top + 11),"Vol : " + str("{:8.2f}".format(voltage)) +"V" , font=font, fill=255)
             draw.text((x, top + 22),"Cur : " + str("{:8.2f}".format(current)) + "A", font=font, fill=255)
             #draw.text((x, top + 0), str("{:6.2f}".format(soc)) +"% : " + str("{:6.2f}".format(voltage)) +"V" , font=font, fill=255)
             #draw.text((x, top + 17),str("{:8.2f}".format(current)) + "A" , font=font, fill=255)

             # Display image.
             disp.image(image)
             disp.show()

             t = threading.Timer(60.0,write2Google)         
             timerFlag=1
             t.start()      
 
def byte2int(bArr, i):
        return (bArr[i + 2] << 24) | (bArr[i + 1] & 255) | ((bArr[i] << 8) & 65280) | ((bArr[i + 3] << 24) >> 8)


def byte2short(bArr, i):
        retInt=(((bArr[i] << 8) & -256) | (bArr[i+1] & 255)).to_bytes(2,'little')
        return(unpack('h'*(len(retInt)//2),retInt)[0])

# Initialisation  -------
whileCount=0
BDLLog.debug("Connecting to google sheet")
scope = ['https://spreadsheets.google.com/feeds',
         'https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('client_secret.json', scope)
client = gspread.authorize(creds)
monYY=datetime.now().strftime('%b%Y')
print("Month Year = "+ monYY.upper())
mobileAppSheet = client.open('BatteryData').worksheet("BDL")
BDLLogsheet = client.open('TIRUCHERAI_BDL_' + monYY.upper()).worksheet("01")
next_row = int(next_available_row(BDLLogsheet))
BDLLog.debug("Next row = " + str(next_row) )

BDLLog.debug("Bluetooth BLE Initializating")
while True:
   try:
         whileCount=whileCount+1
         if whileCount>= 2000:
             resp = subprocess.call("sudo hciconfig hci0 down && sudo hciconfig hci0 up", shell=True)
             BDLLog.debug("Restared bluetooth " + str(resp))
             time.sleep(30)
             whileCount=0
         BDLLog.debug("Starting to scan, count = " + str(whileCount))
         scanner = Scanner().withDelegate(ScanDelegate())
         devices = scanner.scan(10.0)
         BDLName="JEPL15S02849000"
         CHRName="0000ffe1-0000-1000-8000-00805f9b34fb"
         BDLMAC="B8:27:EB:4E:49:EB"
         
         #for dev in devices:
             #for (adtype, desc, value) in dev.getScanData():
                 #if value == BDLName:
                    #BDLMAC=dev.addr
                    #break
                   
         #p = btle.Peripheral(BDLMAC,addrType=btle.ADDR_TYPE_RANDOM)
         p = btle.Peripheral(BDLMAC)
         p.setMTU(200)
         p.setDelegate( MyDelegate())
         chList = p.getCharacteristics()
         for ch in chList:
            if str(ch.uuid) == CHRName:
               BDLLog.debug (ch)
               BDLLog.debug (ch.valHandle)
               break

         desc = ch.getDescriptors(AssignedNumbers.client_characteristic_configuration);
         print(desc[0].handle)
         print(ch.valHandle)
         p.writeCharacteristic(desc[0].handle, b"\x01\x00")
         #p.writeCharacteristic(desc[0].handle, b"\x01\x00")
         BDLLog.debug("Started to listen for MACaddress = " + BDLMAC)
         
         # Main loop --------
         
         while True:
             if p.waitForNotifications(1.0):
                  continue
   
   except BTLEDisconnectError as btlede:
       BDLLog.debug("Device disconnected will start scan again")

   except:
       BDLLog.debug(datetime.now().strftime("%d/%m/%Y %H:%M:%S") + " : Unkown error  will start scan again")
       #resp = subprocess.call("sudo hciconfig hci0 down && sudo hciconfig hci0 up", shell=True)
       #BDLLog.debug("Restared bluetooth " + str(resp))
       time.sleep(30)


stirucherai
 
Posts: 23
Joined: Sun Sep 26, 2021 11:44 am

Re: Adafruit PiOLED - 128x32 Monochrome OLED Showing data sc

by adafruit_support_carter on Mon Sep 27, 2021 4:24 pm

This clears the OLED:
Code: Select all | TOGGLE FULL SIZE
    disp.fill(0)

but since you are using a bitmap image with a PIL ImageDraw, you need to clear the actual bitmap. Otherwise each new update just overwrites on top of the previous text. Can't remember exactly how to do that in PIL though. The Image class doesn't have a clear or fill:
https://pillow.readthedocs.io/en/stable ... mage.Image
I think you can use the Draw to create full screen rectangle? But in general, that's what is happening.

adafruit_support_carter
 
Posts: 21391
Joined: Tue Nov 29, 2016 2:45 pm

Re: Adafruit PiOLED - 128x32 Monochrome OLED Showing data sc

by stirucherai on Mon Sep 27, 2021 4:32 pm

Did understand the message. Can you please provide what i should do

1. Requirement is clear, ever one min the data changes and we need to refresh
2. added fill(0) but that did not solve the problem

Thanks and Regards
Sarang

stirucherai
 
Posts: 23
Joined: Sun Sep 26, 2021 11:44 am

Re: Adafruit PiOLED - 128x32 Monochrome OLED Showing data sc

by adafruit_support_carter on Mon Sep 27, 2021 4:37 pm

Consult the PIL documentation to figure out how to fully clear the bitmap being used in the ImageDraw. This is a PIL usage issue. Not an OLED issue.

adafruit_support_carter
 
Posts: 21391
Joined: Tue Nov 29, 2016 2:45 pm

Re: Adafruit PiOLED - 128x32 Monochrome OLED Showing data sc

by stirucherai on Tue Sep 28, 2021 10:35 am

Ok, Got it working.

Thank and Regards
Sarang

stirucherai
 
Posts: 23
Joined: Sun Sep 26, 2021 11:44 am

Please be positive and constructive with your questions and comments.