简体   繁体   中英

How to change my wxpython program that read and display rain sensor data from mcp3008 to software spi?

I have a completed wxpython code that can read data from rain sensor and convert it from analogue to digital with mcp3008. The problem is the current raspberry pi that I use, already has a 20x4 lcd display that uses pin 24 or GPIO 8 which I need for my rain sensor program. I have read from https://learn.adafruit.com/raspberry-pi-analog-to-digital-converters/mcp3008#software-spi on how to change my spi connection to software spi. Here is my mcp3008 pinout to raspberry pi without lcd display: MCP3008 VDD -> 5V

MCP3008 VREF -> 5V

MCP3008 AGND -> GND

MCP3008 CLK -> pin 23

MCP3008 DOUT -> pin 21

MCP3008 DIN -> pin 19

MCP3008 CS -> pin 24

MCP3008 DGND -> GND

Here is my wxpython code for rain sensor:

import datetime
import spidev
from time import sleep
import os

spi = spidev.SpiDev()
spi.open(0,0)
#global adcOut
adcOut = 0
percent = 0
volts = 0
rain_condition = ""

global current_time
current_time = datetime.datetime.strftime(datetime.datetime.now(), '%d-%m-%y   %H:%M:%S')

try:
    import wx
except ImportError:
    raise ImportError, "The wxPython module is required to run this program."

class RainSensorApp_wx(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, size = (700, 300))
        self.SetBackgroundColour(wx.WHITE)
        self.parent = parent
        self.initialize()

    def initialize(self):
        sizer = wx.GridBagSizer()
        font = wx.Font(20, wx.DECORATIVE, wx.ITALIC, wx.NORMAL)
        self.SetFont(font)
        self.label1 = wx.StaticText(self, -1, label = u'Rain Sensor Level: {0:4d}   Percentage: {1:3}%   Voltage: {2}V'.format(adcOut, percent, volts))

        self.label1.SetBackgroundColour(wx.WHITE)
        self.label1.SetForegroundColour(wx.BLACK)
        sizer.Add(self.label1, (1,0), (1,2), wx.EXPAND)

        self.label2 = wx.StaticText(self, -1, label = u'Rain Condition: {}'.format(rain_condition))
        self.label2.SetBackgroundColour(wx.WHITE)
        self.label2.SetForegroundColour(wx.BLACK)
        sizer.Add(self.label2, (2,0), (1,3), wx.EXPAND)

        self.label3 = wx.StaticText(self, -1, label = u'Time Updated: {}'.format(current_time))
        self.label3.SetBackgroundColour(wx.WHITE)
        self.label3.SetForegroundColour(wx.BLACK)
        sizer.Add(self.label3, (3,0), (1,4), wx.EXPAND)

        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.on_timer, self.timer)
        self.timer.Start(1000)

        self.SetSizer(sizer)
        self.Show(True)

    def on_timer(self,event):
        channel = 0
        if ((channel>7) or (channel<0)):
            return -1

        #r = spi.xfer2([1, (8+channel) << 4, 0])
        #REPLACEMENT
        r = [0]*8
        for i in range(8):
        # The read_adc function will get the value of the specified channel (0-7).
            r[i] = mcp.read_adc(i) 
        #END REPLACEMENT
        adcOut = ((r[1]&3) << 8) + r[2]

        #global adcOut
        percent = int(round(adcOut/10.24))
        volts = ((adcOut/float (1023)) * 5)
        volts = round(volts, 2)

        global current_time
        current_time = datetime.datetime.strftime(datetime.datetime.now(), '%d-%m-%y   %H:%M:%S')
        if adcOut >= 0 and adcOut <= 300:
            self.label1.SetLabel("ADC Output: {0:4d}   Percentage: {1:3}%   Voltage: {2}V".format(adcOut, percent, volts))
            self.label2.SetLabel("Rain Condition: Heavy Rain")
            self.label3.SetLabel("Time Updated: {}".format(current_time))

        elif adcOut >= 0 and adcOut <= 500:
            self.label1.SetLabel("ADC Output: {0:4d}   Percentage: {1:3}%   Voltage: {2}V".format(adcOut, percent, volts))
            self.label2.SetLabel("Rain Condition: Moderate Rain")
            self.label3.SetLabel("Time Updated: {}".format(current_time))

        elif adcOut >= 0 and adcOut <= 700:
            self.label1.SetLabel("ADC Output: {0:4d}   Percentage: {1:3}%   Voltage: {2}V".format(adcOut, percent, volts))
            self.label2.SetLabel("Rain Condition: Light Rain")
            self.label3.SetLabel("Time Updated: {}".format(current_time))

        else:
            self.label1.SetLabel("ADC Output: {0:4d}   Percentage: {1:3}%   Voltage: {2}V".format(adcOut, percent, volts))
            self.label2.SetLabel("Rain Condition: No Rain")
            self.label3.SetLabel("Time Updated: {}".format(current_time))

if __name__ == "__main__":
    Rs = wx.App()
    RainSensorApp_wx(None, -1, 'Rain Sensor Monitor')
    Rs.MainLoop()

Here is the example code from the AdaFruit_MCP3008 after I followed the steps on the web given to install the library:

# Simple example of reading the MCP3008 analog input channels and printing
# them all out.
# Author: Tony DiCola
# License: Public Domain
import time

# Import SPI library (for hardware SPI) and MCP3008 library.
import Adafruit_GPIO.SPI as SPI
import Adafruit_MCP3008


# Software SPI configuration:
CLK  = 18
MISO = 23
MOSI = 24
CS   = 25
mcp = Adafruit_MCP3008.MCP3008(clk=CLK, cs=CS, miso=MISO, mosi=MOSI)

# Hardware SPI configuration:
# SPI_PORT   = 0
# SPI_DEVICE = 0
# mcp = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE))


print('Reading MCP3008 values, press Ctrl-C to quit...')
# Print nice channel column headers.
print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} |     {7:>4} |'.format(*range(8)))
print('-' * 57)
# Main program loop.
while True:
    # Read all the ADC channel values in a list.
    values = [0]*8
    for i in range(8):
        # The read_adc function will get the value of the specified channel (0-7).
        values[i] = mcp.read_adc(i)
    # Print the ADC values.
    print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} | {7:>4} |'.format(*values))
    # Pause for half a second.
    time.sleep(0.5)

Can somebody help me on how to change my program to read data with the software spi, as I need to change the Software spi configuration to:

CLK = 23

MISO = 21

MOSI = 19

CS = 29

Without knowing what Adafruit_MCP3008 is returning and without access to the hardware to be able to test it, I suspect that your existing line:

r = spi.xfer2([1, (8+channel) << 4, 0])

should be replaced by:

r = [0]*8
for i in range(8):
    # The read_adc function will get the value of the specified channel (0-7).
    r[i] = mcp.read_adc(i) 

The only way to know for sure would be to print out r as it is in your current set up and then do the same for the new one, to see if there are any differences and what they are.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM