i want use python to get the cpu_freq value from raspberry pi 4B
def GetCpuInfo():
# Get CPU frequence
cpu_freq =open("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq").read()
return cpu_freq
when i print the cpu_freq data, the output always fixed in 1800000(it's the max cpu frequence 1.8Ghz of raspberry pi),but when each time i use the
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
this command in terminal,it give me the dynamic valve(600000-1800000)
So why do i get wrong value when using the python? is it a wrong way to read this file?
There's nothing wrong with your read().
The very act of starting Python can itself take enough cycles to cause the CPU to ramp up to full frequency, especially on a small system like a Pi.
To prevent that, add a delay to let it spool back down before you take your readings. For example:
import time
def GetCpuInfo():
with open("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq") as f:
return f.read()
for _ in range(20):
time.sleep(1)
print(GetCpuInfo())
Related
Is it possible -- other than by using something like a .txt/dummy file -- to pass a value from one program to another?
I have a program that uses a .txt file to pass a starting value to another program. I update the value in the file in between starting the program each time I run it (ten times, essentially simultaneously). Doing this is fine, but I would like to have the 'child' program report back to the 'mother' program when it is finished, and also report back what files it found to download.
Is it possible to do this without using eleven files to do it (that's one for each instance of the 'child' to 'mother' reporting, and one file for the 'mother' to 'child')? I am talking about completely separate programs, not classes or functions or anything like that.
To operate efficently, and not be waiting around for hours for everything to complete, I need the 'child' program to run ten times and get things done MUCH faster. Thus I run the child program ten times and give each program a separate range to check through.
Both programs run fine, I but would like to get them to run/report back and forth with each other and hopefully not be using file 'transmission' to accomplish the task, especially on the child-mother side of the transferring of data.
'Mother' program...currently
import os
import sys
import subprocess
import time
os.chdir ('/media/')
#find highest download video
Hival = open("Highest.txt", "r")
Histr = Hival.read()
Hival.close()
HiNext = str(int(Histr)+1)
#setup download #1
NextVal = open("NextVal.txt","w")
NextVal.write(HiNext)
NextVal.close()
#call download #1
procs=[]
proc=subprocess.Popen(['python','test.py'])
procs.append(proc)
time.sleep(2)
#setup download #2-11
Histr2 = int(Histr)/10000
Histr2 = Histr2 + 1
for i in range(10):
Hiint = str(Histr2)+"0000"
NextVal = open("NextVal.txt","w")
NextVal.write(Hiint)
NextVal.close()
proc=subprocess.Popen(['python','test.py'])
procs.append(proc)
time.sleep(2)
Histr2 = Histr2 + 1
for proc in procs:
proc.wait()
'Child' program
import urllib
import os
from Tkinter import *
import time
root = Tk()
root.title("Audiodownloader")
root.geometry("200x200")
app = Frame(root)
app.grid()
os.chdir('/media/')
Fileval = open('NextVal.txt','r')
Fileupdate = Fileval.read()
Fileval.close()
Fileupdate = int(Fileupdate)
Filect = Fileupdate/10000
Filect2 = str(Filect)+"0009"
Filecount = int(Filect2)
while Fileupdate <= Filecount:
root.title(Fileupdate)
url = 'http://www.yourfavoritewebsite.com/audio/encoded/'+str(Fileupdate)+'.mp3'
urllib.urlretrieve(url,str(Fileupdate)+'.mp3')
statinfo = os.stat(str(Fileupdate)+'.mp3')
if statinfo.st_size<10000L:
os.remove(str(Fileupdate)+'.mp3')
time.sleep(.01)
Fileupdate = Fileupdate+1
root.update_idletasks()
I'm trying to convert the original VB6 program over to Linux and make it much easier to use at the same time. Hence the lack of .mainloop being missing. This was my first real attempt at anything in Python at all hence the lack of def or classes. I'm trying to come back and finish this up after 1.5 months of doing nothing with it mostly due to not knowing how to. In research a little while ago I found this is WAY over my head. I haven't ever did anything with threads/sockets/client/server interaction so I'm purely an idiot in this case. Google anything on it and I just get brought right back here to stackoverflow.
Yes, I want 10 running copies of the program at the same time, to save time. I could do without the gui interface if it was possible for the program to report back to 'mother' so the mother could print on the screen the current value that is being searched. As well as if the child could report back when its finished and if it had any file that it downloaded successfully(versus downloaded and then erased due to being to small). I would use the successful download information to update Highest.txt for the next time the program got ran.
I think this may clarify things MUCH better...that or I don't understand the nature of using server/client interaction:) Only reason time.sleep is in the program was due to try to make sure that the files could get written before the next instance of the child program got ran. I didn't know for sure what kind of timing issue I may run into so I included those lines for safety.
This can be implemented using a simple client/server topology using the multiprocessing library. Using your mother/child terminology:
server.py
from multiprocessing.connection import Listener
# client
def child(conn):
while True:
msg = conn.recv()
# this just echos the value back, replace with your custom logic
conn.send(msg)
# server
def mother(address):
serv = Listener(address)
while True:
client = serv.accept()
child(client)
mother(('', 5000))
client.py
from multiprocessing.connection import Client
c = Client(('localhost', 5000))
c.send('hello')
print('Got:', c.recv())
c.send({'a': 123})
print('Got:', c.recv())
Run with
$ python server.py
$ python client.py
When you talk about using txt to pass information between programs, we first need to know what language you're using.
Within my knowledge of Java and Python achi viable despite laborious depensendo the amount of information that wants to work.
In python, you can use the library that comes with it for reading and writing txt and schedule execution, you can use the apscheduler.
i am fairly new to the field of IOT. I am setting up a sensor with teensy for reading up its data and transmitting over using serial communication to system where using python I am reading the data and storing it into a database.
The problem I am facing is when i check my program using arduino serial monitor I am getting insane sample speed like 10k readings are done in 40 milli seconds but when i try to read the same program using python it is not even giving me more than 1000 readings per second and that too without the database code with it it only reads 200 samples per second. Is there any way i can increase this sample rate or do i have to set any extra parameters for communication through serial ?
Here is my code for teensy :
int i;
elapsedMillis sinceTest1;
void setup()
{
Serial.begin(2000000); // USB is always 12 Mbit/sec
i = 0;
delay(5000);
Serial.println("Setup Called");
Serial.flush();
}
void loop()
{
if (i == 0 || i == 500000)
{
Serial.println(sinceTest1);
}
Serial.println(i);
//Serial.println(Serial.baud());
i++;
}
For python :
import serial
import pymysql
from datetime import datetime
import time
import signal
import sys
class ReadLine:
def __init__(self, s):
self.buf = bytearray()
self.s = s
def readline(self):
i = self.buf.find(b"\n")
if i >= 0:
r = self.buf[:i+1]
self.buf = self.buf[i+1:]
return r
while True:
i = max(1, min(2048, self.s.in_waiting))
data = self.s.read(i)
i = data.find(b"\n")
if i >= 0:
r = self.buf + data[:i+1]
self.buf[0:] = data[i+1:]
return r
else:
self.buf.extend(data)
ser = serial.Serial(
port='COM5',\
baudrate=2000000,\
#baudrate=9600,\
#parity=serial.PARITY_NONE,\
#stopbits=serial.STOPBITS_ONE,\
#bytesize=serial.EIGHTBITS,\
#timeout=0
)
print("connected to: " + ser.portstr)
count=1
#this will store the line
line = []
#database connection
connection = pymysql.connect(host="localhost", user="root", passwd="", database="tempDatabase")
cursor = connection.cursor()
checker = 0
rl = ReadLine(ser)
while True:
time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(time)
print(checker)
print(rl.readline())
insert1 = ("INSERT INTO tempinfo(value,test,counter) VALUES('{}','{}','{}');".format(33.5, time,checker)) #.format(data[0])
insert2 = ("INSERT INTO urlsync(textvalue,sync) VALUES('http://www.myname.com/value.php?&value={}&time={}',0);".format(33.5,time)) #.format(data[0])
cursor.execute(insert1)
cursor.execute(insert2)
connection.commit()
checker += 1
connection.close()
time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(time )
ser.close()
P.S : 1000 samples per second is the rate I am getting when I am not using the commands for database, including them I am getting around 250 samples per second only.
Any help or suggestion is appreciated, thank you.
First off, great question. The issue you are facing is loaded with learning opportunities.
Let's go one by one:
-You are now in the position to understand the difference between a microcontroller and a computer. The microcontroller in its most basic form (if you are running bare-metal code, even if it's not very efficient code, like on an Arduino) will do just one thing, and particularly when it's hardware-related (like reading or writing to UARTs) it will do it very efficiently. On a desktop computer, on the other hand, you have layer upon layer of tasks running simultaneously (operating system background tasks, updating the screen and whatnot). With so many things happening at the same time and if you don't establish priorities, it will be very difficult to accurately predict what will exactly happen and when. So it's not only your Python code that is running, there will be many more things that will come up and interrupt the flow of your user task. If you are hoping to read data from the UART buffer at a stable (or at least predictable) speed, that will never happen with the architecture you are using at the moment.
-Even if you manage to strip down your OS to the bare minimum, kill all processes, go on a terminal with no graphics whatsoever... you still have to deal with the uncertainty of what you are doing on your own Python code (that's why you see better performance with the Arduino serial monitor, which is not doing anything other than removing data from the buffer). On your Python code, you are sequentially reading from the port, trying to find a particular character (line feed) and then attaching the data you read to a list. If you want to improve performance, you need to either just read data and store it for offline processing or look at multithreading (if you have a thread of your program dedicated to only reading from the buffer and you do further processing on a separate thread you could improve significantly the throughput, particularly if you set priorities right).
-Last, but actually, most importantly, you should ask yourself: Do I really need to read data from my sensor at 2 Mbps? If the answer is yes, and your sensor is not a video camera, I'm afraid you need to take a step back and look at the following concepts: sensor bandwidth and dynamic response. After you do that, the next question is: how fast is your sensor updating its output and why? is that update rate meaningful? I can give you a couple of references here. First, imagine you have a temperature sensor to read and record the temperature in an oven. Does it make sense to sample values from the sensor at 1 MHz (1 million readings per second) if the temperature in the oven is changing at a rate of 10 degrees C per minute or even 100 degrees per second? Is your sensor even able to react so fast (that where its dynamic response comes into play)? My guess: probably not. Many industrial devices integrate dozens of sensors to control critical processes and send all data through a 1.5 Mbps link (pretty standard for Profibus, for instance).
I currently have an arduino code, which is connected to three sensors: temperature, pressure and humidity. I would like to make a code in python that of an order (by int or strg), this sends the type of sensor that I want to read, example: if I enter by keyboard 1, it constantly sends me temperature data; if income 2, send me pressure data; and thus be able to enter any digit at any time.
Pd: Sorry my bad english,I don't know if i could explain my problem
I have a similar code in arduino with switch case, and it works perfectly. but I can not make it work in python since when I put raw_input (), the program stops waiting for input and stops reading the sensor data.
Python
import serial
import time
ser=serial.Serial('/dev/ttyUSB0',baudrate=115200)
while 1:
ser.setDRT(False)
#c=raw_input()
#ser.write(c)
med=a.readline()
print med
this just works fine to read data from one sensor type assigned by default
If you have tasks, that needs to run in parallel, you can use threads. One thread gets the sensor data and the other waits for input.
Python has a very easy to use builtin module for threading.
Official python docs: https://docs.python.org/3.7/library/threading.html
Tutoialspoint: https://www.tutorialspoint.com/python/python_multithreading.htm
A very simple implementation example might look like this:
import threading
def wait_input():
while True:
user_input = input()
# do something with user_input
def get_sonsordata()
while True:
med=a.readline()
print(med)
input_thread = threading.Thread(target=wait_input)
input_thread.start()
sensor_thread = threading.Thread(target=get_sonsordata)
sensor_thread.start()
So I started a project on a microcontroler that uses I2C communication a month ago with no knowledge about anything but python.
I have to talk to a peristaltic pump that uses ASCII strings for communication.
So my setup currently consists of a Raspberry Pi, the I2C bus, Arduino and the peristaltic pump. The Arduino is only used as a powersupply. I thought a good starting point would be just to try and turn the pumps LED on and off. The code for LED on is "L,1" and for LED off is "L,0". (The "" indicates that whats inside it is the absolute code). [a link] https://www.atlas-scientific.com/_files/_datasheets/_peristaltic/EZO_PMP_Datasheet.pdf
By using smbus.SMBus in python I sent the data through the command through write_i2c_block_data. Documentation of smbus gives the following: write_i2c_block_data(int addr,char cmd,long vals[]) however i dont understand what is meant with 'char cmd'. I couldnt put a string command in there and it only worked when I put an integer in there.
Here is the code:
import smbus
import time
bus = smbus.SMBus(1)
slave_address = 0x67
led_on = 'L,1'
led_off = 'L,0'
def string_to_charlist(a_string):
stringlist = list(a_string)
return stringlist
def string_to_intlist(a_string):
lst = string_to_charlist(a_string)
intlist = []
for i in range(len(lst)):
an_int = string_to_charlist(lst[i])
intlist.append(an_int)
return intlist
ledon_intlist = string_to_intlist(led_on)
ledoff_intlist = string_to_intlist(led_off)
# this will result in ledon_intlist = [76,44,49]
# this will result in ledon_int =list [76,44,48]
command1_on = ledon_intlist.pop(0)
command1_off = ledoff_intlist.pop(0)
for i in range(1):
time.sleep(0.5)
bus.write_i2c_block_data(slave_address, command1_on, ledon_intlist)
time.sleep(0.5)
bus.write_i2c_block_data(slave_address, command1_on, ledon_intlist)
After running this code through the raspberry Pi command prompt the pumps LED started blinking on the given time frame. Unfortunately it never stopped blinking and also didt show up when I searched for it using i2ctools command i2cdetect -y 1 I assume the pump's chip is in an infinite loop now.
My questions are:
1. How should one use the write_i2c_block_data() command and what argument does it take. Currently I figured that the 1st argument is the slave address, 2nd is the initial byte of the stream and the 3rd argument is the rest of the stream integer values to be sent.
2. What possibly could have gone wrong that the pump is stuck in an infinite loop and how do I fix it
So I have a bit of a conundrum. Let's start with the relevant fragment of my code.
from RECORD import recordSystem
recTime = 30 #Amount of time(seconds) I want to record the audio input
while True: #I want to keep this active while system is running
#Standard raspberry Pi input sensors.
if(GPIO.input(LedPin4) == GPIO.LOW and GPIO.input(LedPin5) == GPIO.HIGH:
recordSystem(recTime) #when condition is met run the code.
So the function I am trying to run comes from another script I wrote. And it works. It records analog audio and creates a .wav file in my project folder. The problem with this code is that it was working perfectly find yesterday and now is not. Nothing has been changed or touched. It just does not want to work. What happens is that the loop starts, and when the condition is met the function is launched properly and I get my "recording" notice in the compiler. Yet it NEVER stops recording.
When I just do the following outside of the loop:
recordSystem(recTime)
The function runs through properly without any problems. So it has to do something with calling the function inside the loop. Yet, it was working without any problems for a while.
Could anyone give me a best guest on what might be going on?
Much appreciated!
Adding a break statement after your recordSystem(recTime) should do the trick! I also fixed the indentation, and removed an extra ( from the code:
from RECORD import recordSystem
recTime = 30 #Amount of time(seconds) I want to record the audio input
while True: #I want to keep this active while system is running
#Standard raspberry Pi input sensors.
if GPIO.input(LedPin4) == GPIO.LOW and GPIO.input(LedPin5) == GPIO.HIGH:
recordSystem(recTime) #when condition is met run the code.
break