2

so i've got some values coming in from an Arduino to my Raspberry Pi via an RF transceiver (NRF24L01) and i can display the integers when the program runs (Python). Now i want to display those integer values in my GUI that i've written in a seperate python script. I'm having trouble doing so. I've tried importing them from the GUI but it isn't working and i couldn't figure out why..

So now i've gone with the option of writing the value into a text file in the transmission script and then attempting to read the value from the text file in the GUI script but it still dosent work completely.

Can anyone help me update the text file from the transmission script and read it from the GUI script? Can you write to a text file from one script and read the text file from another script at the same time?

ANY help will be greatly appreciated. Thanks!

ps. If iv'e missed out on anything that you need to know just ask. It's a little hard to explain everything!

GUI CODE

# -*- coding: utf-8 -*-
"""
Created on Sat Aug  6 20:05:30 2016

@author: s
"""
import sys

if sys.version_info[0] < 3:
    import Tkinter as tk
else:
    import tkinter as tk


def clear():
    pass


def exit_():
    root.quit()
    root.withdraw()


#water_amount = 0
water_cost = 0
total_water_amount = 0
total_water_cost = 0



def show_data():
    while True:
        text_file = open("Output.txt", "r")
        water_amount = text_file.readlines()
        text_file.close()

        tk.Label(root, text='Water Amount: ' + str(water_amount)).pack()
        tk.Label(root, text='Water Cost: ' + str(water_cost)).pack()

        separator = tk.Frame(height=2, bd=10, relief=tk.SUNKEN)
        separator.pack(fill=tk.X, padx=5, pady=5)

        tk.Label(root, text='Total Water Amount: ' + str(total_water_amount)).pack()
        tk.Label(root, text='Total Water Cost: ' + str(total_water_cost)).pack()

        separator = tk.Frame(height=2, bd=10, relief=tk.SUNKEN)
        separator.pack(fill=tk.X, padx=5, pady=5)

#show_data()


def get_rate():
    import random
    for i in range(100):
        flow_rate.append(random.randint(20, 60))
        # print(flow_rate)


# def draw_plot(flow_rate):
#     import matplotlib.pyplot as plt
#     conda install matplotlib
#     print(flow_rate)
#     plt.plot(flow_rate, label='Flow rate ml/sec')
#     plt.xlabel('Time(sec)')
#     plt.ylabel('Flow Rate(ml)')
#     plt.title("Flow Rate Chart")
#
#     plt.legend()
#     plt.show()


root = tk.Tk(className='Water')
flow_rate = []
get_rate()
show_data()
tk.Button(root, text='Clear', command=clear).pack(side='left')
tk.Button(root, text='Exit', command=exit_).pack(side='left')
#tk.Button(root, text='Draw', command=draw_plot(flow_rate)).pack_forget()



root.mainloop()

CODE RECEIVING VALUES

import RPi.GPIO as GPIO
from lib_nrf24 import NRF24
import time
import spidev

GPIO.setmode(GPIO.BCM)

pipes = [[0xE8, 0xE8, 0xF0, 0xF0, 0xE1], [0xF0, 0xF0, 0xF0, 0xF0, 0xE1]]

radio = NRF24(GPIO, spidev.SpiDev())
radio.begin(0,17)

radio.setPayloadSize(32) #can have maximum 32
radio.setChannel(0x76)
radio.setDataRate(NRF24.BR_1MBPS) #Slower since it is secure
radio.setPALevel(NRF24.PA_MIN) # Minimum to save battery

radio.setAutoAck(True)
radio.enableDynamicPayloads()
radio.enableAckPayload() #Acknowledgement Payload : Can verify if data received

radio.openReadingPipe(1, pipes[1])
radio.printDetails()
radio.startListening()

while True:

    # Waits to recieve data, if no data is recieved then goes into sleep mode
    while not radio.available(0):
        time.sleep(1/100)


    receivedMessage = []
    #Populates the message
    radio.read(receivedMessage, radio.getDynamicPayloadSize())

    #-------------------------------------------------------
    raw = int(receivedMessage[1]) * 256
    total = raw + int(receivedMessage[0])
    print ("total equals:" + str(int(total)))
    text_file = open("Output.txt", "w")
    text_file.write("%s" % total)
    text_file.close()
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
George
  • 21
  • 1
  • 1
    What does "isn't working" and "still doesn't work" mean? – Bryan Oakley Aug 22 '16 at 12:12
  • This answer shows a better way to poll a sensor than to use sleep: http://stackoverflow.com/a/37681471/7432 – Bryan Oakley Aug 22 '16 at 12:33
  • You might want to see if [pipes](http://stackoverflow.com/a/3806342/3901060) will do what you want. You will have to modify the code in that answer since you are using two separate scripts. – FamousJameous Aug 22 '16 at 14:22

1 Answers1

1

You should try to combine the data-receiving code and data-displaying code with threading library.

In the while True loop in the data-receiving script, it should check for new result and notify the GUI thread somehow (eg. store it in a global variable and use the threading.Condition object), or change the GUI directly.

For example:

from tkinter import *
import threading

tk=Tk()
result=StringVar()

Label(tk,textvariable=result).pack()

def update_result():
    import RPi.GPIO as GPIO
    from lib_nrf24 import NRF24
    import time
    import spidev

    GPIO.setmode(GPIO.BCM)

    pipes = [[0xE8, 0xE8, 0xF0, 0xF0, 0xE1], [0xF0, 0xF0, 0xF0, 0xF0, 0xE1]]

    radio = NRF24(GPIO, spidev.SpiDev())
    radio.begin(0,17)

    radio.setPayloadSize(32) #can have maximum 32
    radio.setChannel(0x76)
    radio.setDataRate(NRF24.BR_1MBPS) #Slower since it is secure
    radio.setPALevel(NRF24.PA_MIN) # Minimum to save battery

    radio.setAutoAck(True)
    radio.enableDynamicPayloads()
    radio.enableAckPayload() #Acknowledgement Payload : Can verify if data received

    radio.openReadingPipe(1, pipes[1])
    radio.printDetails()
    radio.startListening()

    while True:
        while not radio.available(0):
        time.sleep(1/100)

        receivedMessage = []
        #Populates the message
        radio.read(receivedMessage, radio.getDynamicPayloadSize())

        #-------------------------------------------------------
        raw = int(receivedMessage[1]) * 256
        total = raw + int(receivedMessage[0])
        result.set(total)


threading.Thread(target=update_result).start()
mainloop()

(I didn't test this program because I don't have the environment, but I think that should work. Please comment if it's not working.)

xmcp
  • 3,347
  • 2
  • 23
  • 36
  • So what your saying is that i can now call "total" from the GUI script using the threading function? – George Aug 23 '16 at 04:27
  • `global total` in the update_result function, and the GUI code should be able to access the variable directly – xmcp Aug 23 '16 at 05:14