abusaeedmirza
Posts: 59
Joined: Tue Mar 06, 2018 3:02 pm

getting values from variable and storing it to array

Mon Mar 19, 2018 6:28 pm

hello!
i want to take mean of the first 10 values from the result of 'voltage' variable (mentioned in code below) . can anyone help me how to do it?

Code: Select all

from time import sleep
import RPi.GPIO as GPIO
import spidev
import numpy as np
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(11,GPIO.OUT)
spi= spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz= 250000
def poll_sensor(channel):
        assert 0 <= channel <= 1 
        if channel:
                cbyte=0b11000000
        else:
                cbyte=0b10000000
        r=spi.xfer2([1,cbyte,0])
        return ((r[1]&31)<<6) + ( r[2]>>2)
try:
        while True:
                channel=0
                channeldata=poll_sensor(channel)
                voltage = round(((channeldata*5.0)/1024),0)

                print ('voltage    : {}'.format(voltage))
                print ('data       : {}\n'.format(channeldata)  )
                my_volt=list(map(float,voltage)
                print ( my_volt[0:10]) 
                print(np.mean(my_sal[0:10]))
                if channeldata<=500:
                        GPIO.output(11,True)
                        sleep(2)
                        GPIO.output(11, False)
                        sleep(2)
                else:
                        print ('liquid is ok')

                sleep(2)



finally:
        spi.close()
        print"\n all cleaned up"
GPIO.cleanup()
[code/]
'voltage' variable is in the while loop and 'my_volt' list will take first 10 values from the variable and will show the mean value. 
can anyone help me in this code that where i am wrong?

User avatar
OutoftheBOTS
Posts: 660
Joined: Tue Aug 01, 2017 10:06 am

Re: getting values from variable and storing it to array

Mon Mar 19, 2018 8:57 pm

If I understand what you want to do is have an array of 10 items of data and when ever new data becomes available then add it to the data array but at the same time remove the oldest data so there is only the latest 10 readings then display the average of latest 10 readings.

Code: Select all

data_array = [0,0,0,0,0,0,0,0,0,0] #can also be written as data_arrray = [0] * 10

while True:
  new_data = poll_sensor() #get new data
  for pos in range( 9, 0, -1): data_array[position] = data_arrray[pos-1] #move all data along the array
  data_array[0] = new_data # place the new data in first position
  average_value = 0 #set average to 0
  for pos in range(10): average_value += data_array[pos] #incrediment by the data in the array
  average_value /= 10 #divide by 10

Adaulith
Posts: 17
Joined: Thu Oct 19, 2017 8:47 pm

Re: getting values from variable and storing it to array

Tue Mar 20, 2018 1:09 am

I've made a class that looks like will also work for what you need. I use it for my live streaming graph for sensor inputs.

Code: Select all

import datetime

class graph_data:
	def __init__(self, x, y):
		self.max_points = x # the max amount of points to store in the list.  Defined in the setpoints for each sensor
		self.graph_list = [] # initlize the list
		self.name = y # info as to what is being stored in the list
		self.time_stamps = [] # initilizes list to store time stamps
	
	def update_data(self, new_point):
		# if the current length of the list is less then the max length, simply append the new data point to the end of the list
		if (len(self.graph_list) < self.max_points):
			self.graph_list.append(new_point)
			now = datetime.datetime.now()
			current_time = now.strftime('%Y/%m/%d %H:%M:%S')
			self.time_stamps.append(current_time)
		else:
			for x in range (0, len(self.graph_list)):
				if ((x + 1) < len(self.graph_list)):
					self.graph_list[x] = self.graph_list[x + 1] # moves value from one greater index value to current index value
					self.time_stamps[x] = self.time_stamps[x + 1]
				else:
					self.graph_list[x] = new_point
					self.time_stamp(x)
		return
	
	def time_stamp(self,x):
		now = datetime.datetime.now()
		current_time = now.strftime('%Y/%m/%d %H:%M:%S')		
		self.time_stamps[x] = current_time
		return 		
	
	def print_list(self):
		# print the entire list by index value and name to terminal
		print ('\nPrinting '+ self.name + ' to terminal.')
		for x in range (0, len(self.graph_list)):
			print (self.name + '[' + str(x) + ']' + str(self.graph_list[x]))
		return
	
	def return_value(self, x):
		# return a specific value
		return self.graph_list[x]
	
	def return_list(self):
		# return the whole list
		return self.graph_list
		
	def return_timeStamp(self):
		return self.time_stamps
		
	def running_average(self):
		average = 0
		avg_list = self.return_list()
		y = len(avg_list)
		try:
			if (y < 4): # if the length of the list is less then 5, just average the length of the list
				for x in range (0, y):
					average = average + float(avg_list[x])
				average = average / y		
			else: # otherwise average the last 5 values added to the list
				for x in range (1, 6):
					average = average + float(avg_list[(y-x)])
				average = average / 5.0
		except ZeroDivisionError:
			return average
	
		return average #returns the average for the last 5 values.
it is actually two arrays, the second being a timestamp.
you can change the running average to 10 or whatever. I've been meaning to update it so when you initialize the class you can set the number of points to average.

User avatar
OutoftheBOTS
Posts: 660
Joined: Tue Aug 01, 2017 10:06 am

Re: getting values from variable and storing it to array

Tue Mar 20, 2018 6:35 am

@adaulita

Nice useful object.

Just out of neatness would it be slightly better to store the time stamp with the data in a 2 dimensional array.

Something like this [ [time, data], [time, data], [time, data], [time,data], [time, data], [time, data], [time, data], [time,data] ]

abusaeedmirza
Posts: 59
Joined: Tue Mar 06, 2018 3:02 pm

Re: getting values from variable and storing it to array

Tue Mar 20, 2018 11:39 am

thanks for the replay.
i just need first 10 values from 'voltage' variable, those first 10 values will go in array and then i need to print the mean or average of the array.

Adaulith
Posts: 17
Joined: Thu Oct 19, 2017 8:47 pm

Re: getting values from variable and storing it to array

Tue Mar 20, 2018 1:30 pm

OutoftheBOTS wrote:
Tue Mar 20, 2018 6:35 am
@adaulita

Nice useful object.

Just out of neatness would it be slightly better to store the time stamp with the data in a 2 dimensional array.

Something like this [ [time, data], [time, data], [time, data], [time,data], [time, data], [time, data], [time, data], [time,data] ]
Thanks,
You're right it probably would be. This was one of the first standalone objects that I wrote. Only been using python for a few months.
There's a few changes I want to make to it yet. Something I should do. I've seen this question like this pop up a few times in various forms on this forum.

I think I will take your advice and change it to a two dimensional array, will be easy enough. The program that I made that uses it though will have to use the old version though :D, I'd have to change a lot of code in it, and that's something I have no desire to do at the moment :lol:

Adaulith
Posts: 17
Joined: Thu Oct 19, 2017 8:47 pm

Re: getting values from variable and storing it to array

Tue Mar 20, 2018 3:06 pm

Here is something I put together. It should do what you need. I still made it an object but simplified it. Here is the object to store and average the data.

Code: Select all

class averageData:
	def __init__(self, x, y, z ):
		self.maxPoints = x #Sets the maximum number for the array
		self.varList = [] #Initialize the list
		self.name = z #Name of what is being stored in the list
		self.averagePoints = y #Number of points to average
		
	def updateData(self, newData):
		#if the current length of the list is less then the max length
		#append the new data point to the end of the list
		if(len(self.varList) < self.maxPoints):
			self.varList.append(newData)
		else:
			for x in range (0, len(self.varList)):
				if ((x + 1) < len(self.varList)):
					self.varList[x] = self.varList[x + 1]
				else:
					self.varList[x] = newData
		return
		
	def printList(self):
		#Print the list to the terminal window
		print ('\nPrinting ' + self.name + ' to the terminal.')
		for x in range(0, len(self.varList)):
			print (self.name + '[' + str(x) + ']' + str(self.varList[x]))
		return
	
	def returnList(self):
		#Return the whole list
		return self.varList
	
	def runningAverage(self):
		#Returns the average of the specified number of points
		average = 0.00
		avgList = self.returnList()
		y = len(avgList)
		try:
			if (y < self.averagePoints):
				#If the length of the list is less then the total points
				#to average, just average the number in the list
				for x in range (0, y):
					average = average + float(avgList[x])
				average = average / y
			else:
				#Average the specified number of points
				for x in range (1, (1 + self.averagePoints)):
					average = average + float(avgList[(y-x)])
				average = average / self.averagePoints
		except ZeroDivisionError:
			print ('Division by zero')
			return average
		return average
Initialize the object

Code: Select all

def main():
	voltageData = averageData(10, 10, 'Voltage')	

if __name__ == "__main__":
    main()
To add data just call the updateData function in it. It will only store the 10 numbers
To get the average, call the runningAverage

Code: Select all

def main():
	voltageData = averageData(10, 10, 'Voltage')
	newVoltageNumber = #New voltage from sensor
	voltageData.updateData(newVoltageNumber)
	voltageAverage = voltageData.runningAverage()	

if __name__ == "__main__":
    main()

This has the added advantage that you can easily change the number of points stored and to average, if you choose to do so in the future. Otherwise it should work for what you need.

abusaeedmirza
Posts: 59
Joined: Tue Mar 06, 2018 3:02 pm

Re: getting values from variable and storing it to array

Wed Mar 21, 2018 2:46 pm

hello!
can you modify my code with the function you are suggesting me. because i didnt understand at all. i am not that good in python . Thank you so much

Adaulith
Posts: 17
Joined: Thu Oct 19, 2017 8:47 pm

Re: getting values from variable and storing it to array

Thu Mar 22, 2018 2:38 pm

Code: Select all

import spidev
import numpy as np

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(11, GPIO.OUT)

spi = spidev.SpiDev()
spi.max_speed_hz = 250000

def poll_sensor(channel):
        assert 0 <= channel <= 1 
        if channel:
                cbyte=0b11000000
        else:
                cbyte=0b10000000
        r = spi.xfer2([1,cbyte,0])
        return ((r[1]&31)<<6) + ( r[2]>>2)


        
class averageData:
	def __init__(self, x, y, z ):
		self.maxPoints = x #Sets the maximum number for the array
		self.varList = [] #Initialize the list
		self.name = z #Name of what is being stored in the list
		self.averagePoints = y #Number of points to average
		
	def updateData(self, newData):
		#if the current length of the list is less then the max length
		#append the new data point to the end of the list
		if(len(self.varList) < self.maxPoints):
			self.varList.append(newData)
		else:
			for x in range (0, len(self.varList)):
				if ((x + 1) < len(self.varList)):
					self.varList[x] = self.varList[x + 1]
				else:
					self.varList[x] = newData
		return
		
	def printList(self):
		#Print the list to the terminal window
		print ('\nPrinting ' + self.name + ' to the terminal.')
		for x in range(0, len(self.varList)):
			print (self.name + '[' + str(x) + ']' + str(self.varList[x]))
		return
	
	def returnList(self):
		#Return the whole list
		return self.varList
	
	def runningAverage(self):
		#Returns the average of the specified number of points
		average = 0.00
		avgList = self.returnList()
		y = len(avgList)
		try:
			if (y < self.averagePoints):
				#If the length of the list is less then the total points
				#to average, just average the number in the list
				for x in range (0, y):
					average = average + float(avgList[x])
				average = average / y
			else:
				#Average the specified number of points
				for x in range (1, (1 + self.averagePoints)):
					average = average + float(avgList[(y-x)])
				average = average / self.averagePoints
		except ZeroDivisionError:
			print ('Division by zero')
			return average
		return average


def main():
	voltageData = averageData(10, 10, 'Voltage')
	channel = 0
	try:
		while True:			
			channeldata = poll_sensor(channel)
			voltage = round(((channeldata*5.0)/1024),0)
			
			voltageData.updateData(voltage) #Send the new voltage data to the list
			voltageData.printList() #Print the entire list
			print('\nAverage Voltage: ' + str(voltageData.runningAverage())) #Print the average

			#print ('voltage    : {}'.format(voltage))
			#print ('data       : {}\n'.format(channeldata))				
			
			if channeldata<=500:
				GPIO.output(11,True)
				sleep(2)
				GPIO.output(11, False)
				sleep(2)
			else:
				print ('liquid is ok')
			sleep(2)

	finally:
		spi.close()
		print("\n all cleaned up")
	GPIO.cleanup()
	
if __name__ == "__main__":
    main()

This should work, I can't test it out because I don't have the right sensor, let me know.

abusaeedmirza
Posts: 59
Joined: Tue Mar 06, 2018 3:02 pm

Re: getting values from variable and storing it to array

Sat Mar 24, 2018 5:21 pm

Thank you so much for the help. its woking now.

abusaeedmirza
Posts: 59
Joined: Tue Mar 06, 2018 3:02 pm

Re: getting values from variable and storing it to array

Sat Mar 24, 2018 6:20 pm

thank you for the help.
i want to save the average of the first 10 voltage value for the next use when ever sensor will activate. so according to the average value of the sensor which is already saved, it can do further things.
do you have any idea how to do it?
and i also i want to set limit for the average value. sensor should have capacity of +0.5volt above average value and -0.5 below average value.for example if the average value of voltage is 2.0. it should have capacity to accept anything between 1.5volt to 2.5volt.
i would really appreciate your help.

Thank you.

Adaulith
Posts: 17
Joined: Thu Oct 19, 2017 8:47 pm

Re: getting values from variable and storing it to array

Sun Mar 25, 2018 12:19 am

Do you want just the last average of 10 values? Or to log all of the average of 10 values?
Do you want to be able to pull up the last average on the start of a new script?

Do you want the program to give an error if the sensor is >0.5volts, or just not accept the data?

abusaeedmirza
Posts: 59
Joined: Tue Mar 06, 2018 3:02 pm

Re: getting values from variable and storing it to array

Sun Mar 25, 2018 9:40 am

yes i have modified the code little and i am able to get average of the last 10 values.
i want to set the limit. it is more like calibration. when the sensor is used for first time, it should save the value of the voltage. for example, if the first time sensor gives 2.0 volt average, so our program should be able to save array of voltage from 1.5volt to 2.5volt. and it should not respond to any voltage value which outside of this range in future use of the sensor.
for user program will start like this:
if you using this machine for the 1st time press 1 or to skip press 2.
if 1 is pressed then it go through all that process of getting the average voltage value of last 10 values and it will create an array [-0.5volt from average voltage value....... average voltage value......+0.5volt from average value of the voltage]
(this process will happen only once in month or year)
if 2 is pressed to skip then the program will use the saved array value for further process. if sensor will sense anything outside of the range of the saved array it will print "error".

PingoBags
Posts: 47
Joined: Mon Nov 06, 2017 10:53 pm
Location: NS, Canada

Re: getting values from variable and storing it to array

Sun Mar 25, 2018 12:06 pm

You won't need a key press for that, you don't even need to store the voltages in an array to get the mean.
Just calculate it on the fly.

Example, have 3 variables for storing outside of the while loop, not within it.

Code: Select all

TheMean,TenCount,TotalVolt = 0,0,0
And in your current while loop, just after you set the current voltage

Code: Select all

  voltage = round(((channeldata*5.0)/1024),0)
  
  if TenCount < 10:#Mean not calculated. Will only calculate once, when the script is first run.
    TenCount += 1
    TotalVolt += voltage
    TheMean = TotalVolt / TenCount

  if TenCount == 10:#Mean calculated
    if voltage >= (TheMean - .5) and voltage <= (TheMean + .5): #Voltage in range of mean.  -0.5 / +0.5 
      #Do something here
That's all you need to do.

abusaeedmirza
Posts: 59
Joined: Tue Mar 06, 2018 3:02 pm

Re: getting values from variable and storing it to array

Mon Mar 26, 2018 8:45 am

thank you so much for the reply.
i want to store mean value for the future use. next time when sensor will get on it should use the average value which has been calculated earlier .

Return to “Python”

Who is online

Users browsing this forum: No registered users and 14 guests