Page 1 of 1

MCP 3008 Chip sending data to CSV file via switch

Posted: Thu May 17, 2018 2:19 pm
by Ghwana
Hi, I'm trying to send data from RPi via MCP3008 chip, but keep getting error in code, please see code below, not sure where I've gone wrong!

Code: Select all

#!/usr/bin/python
 
import spidev
import RPi.GPIO as GPIO
import time
import os

# GPIO setup
GPIO.setmode (GPIO.BCM)
GPIO.setwarnings(False)

switch = 18
GPIO.setup(switch, GPIO.IN)

#Define Variables
delay = 0.5


#Create SPI
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz=1000000
 
def readadc(adcnum):
    # read SPI data from the MCP3008, 8 channels in total
    if adcnum > 7 or adcnum < 0:
        return -1
    r = spi.xfer2([1, 8 + adcnum << 4, 0])
    data = ((r[1] & 3) << 8) + r[2]
    return data





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] = readadc(i) + "n"
    # 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 one second.
    time.sleep(1)

    while GPIO.input(switch) == 0:
        time.sleep (0.5)
     
    # write results data to file        
                      
        with open("/home/pi/data_log.csv", "a") as file:
            if os.stat("/home/pi/data_log.csv").st_size == 0:
                file.write("readadc(i)\"n")
            file.write(results)
        # if sensors write to file to often increase this time
        
        time.sleep (2) 
    
    #KeyboardInterrupt:
    print("keyboard interrupt detected, File closed")       
    file.close()    
This is the error

Code: Select all

eError: unsupported operand type(s) for +: 'int' and 'str'
>>> 
Not sure what I'm doing wrong!

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Thu May 17, 2018 3:17 pm
by scotty101
Which line is throwing the error? There are a few candidates.
The error suggests that you are trying to add an integer to a string. If you want to append a number to a string then you need to cast the number to a string
Or if you want to add two values together then you need to cast the string to a integer.

Perhaps you could explain what your program is supposed to do as well. From reading the code, I can't figure out why you would be trying to do what the code is actually telling python to do.

For example;
"file.write(results)" - You have no variable called results.
"file.write("readadc(i)\"n")" - This will just write the text "readadc(i)\"n" to the file not the results of the readadc function.
You have both a file context manager "with open("/home/pi/data_log.csv", "a" as file" and a "file.close()", the context manager will close the file for you.

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Thu May 17, 2018 6:12 pm
by pcmanbob
Well without all of the error message its hard to tell but this line does not look right

Code: Select all

file.write("readadc(i)\"n")
3 sets of quotes cant be .........

and I don't think you are sending the right data to the file, because the readadc(i) was originally in a loop that stepped through each of the inputs on the adc and added the answer to values and its these valuse that were then displayed using the line

Code: Select all

 print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} | {7:>4} |'.format(*values))
 
that used the .format to place then in the correct places on the printed line.

lastly you have a line to right to the file

Code: Select all

file.write(results)
but you don't actually assign any values to the variable results.

you need to create a loop to read the inputs to the adc and create a line using these values that you will then be written to the file.

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Fri May 18, 2018 9:58 am
by Ghwana
Hi, I just want the adc channel values to be showing on RPi and sent to csv through switch, I'm not sure how to set a loop, I thought the loop had already been set, in code below:

Code: Select all

# 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] = readadc(i)
I'm not actually sure, I've looked at this code and it's not really making any sense.

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Fri May 18, 2018 10:15 am
by scotty101
You have a loop to read from the ADC channels but you haven't included in that loop the code to write each reading to the file.

You can either combine the reading a writing to a single loop

Code: Select all

for i in range(8):
    value[i] = readadc(i)
    #write value[i] to file
Or have two seperate loops, one to read ADC and one to write to file

Code: Select all

for i in range(8):
    value[i] = readadc(i)
    
for i in range(8):
    #write value[i] to file

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Fri May 18, 2018 10:23 am
by scotty101
Ghwana wrote:
Fri May 18, 2018 9:58 am
sent to csv through switch,
What does "through switch" mean?

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Fri May 18, 2018 10:28 am
by Ghwana
Sorry, when switch is on data is sent to csv file, when switch is off, data stops being sent to csv file.

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Fri May 18, 2018 10:33 am
by scotty101
So you probably need to change your code. At the moment your while loop where you read the GPIO pin won't do what you expect.

Here is some psuedo code for you

Code: Select all

While Loop - Infinite
    Loop for each of the 8 ADC channels
        Read ADC channel i and store it to values[i]
    End loop
    
    print out to screen all 8 ADC channels
    
    if button is pressed
        Open the csv file
        write 8 ADC values to file
        Close csv file
        
    Wait for a while
        
End Loop
You have all the code there, it's just in the wrong order :lol:

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Fri May 18, 2018 10:36 am
by Ghwana
OK, so please see amended code below:

Code: Select all

#!/usr/bin/python
 
import spidev
import RPi.GPIO as GPIO
import time
import os

# GPIO setup
GPIO.setmode (GPIO.BCM)
GPIO.setwarnings(False)

switch = 18
GPIO.setup(switch, GPIO.IN)

#Define Variables
delay = 0.5


#Create SPI
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz=1000000
 
def readadc(adcnum):
    # read SPI data from the MCP3008, 8 channels in total
    if adcnum > 7 or adcnum < 0:
        return -1
    r = spi.xfer2([1, 8 + adcnum << 4, 0])
    data = ((r[1] & 3) << 8) + r[2]
    return data





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] = readadc(i)
        write values[i] to file
    # 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 one second.
    time.sleep(1)

    while GPIO.input(switch) == 0:
        time.sleep (0.5)
     
    # write results data to file        
                      
        with open("/home/pi/data_log.csv", "a") as file:
            if os.stat("/home/pi/data_log.csv").st_size == 0:
                file.write('values[i]')
            #file.write(results)
        # if sensors write to file to often increase this time
        
        time.sleep (2) 
    
    #KeyboardInterrupt:
    #print("keyboard interrupt detected, File closed")       
    #file.close()    
I'm going to try this and see if it works

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Fri May 18, 2018 10:41 am
by Ghwana
It doesn't like values.

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Fri May 18, 2018 10:44 am
by scotty101
It won't... unless you happen to want a file that just says

Code: Select all

values[i]
values[i]
values[i]
values[i]
values[i]
values[i]
values[i]
values[i]
.... 
1. Read the psuedo code I gave you.
2. Realise that file.write('values[ ­i]') will just output the text values[ i] not the i-th value of the array called values.
3. Psuedo code is a textual description of what your code should do not something to copy and paste in to a program. When I put "write values[ ­i] to file" in my psuedo-code you should have written the code to actually write the values to the file not just the psuedo-code text.­

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Fri May 18, 2018 10:55 am
by Ghwana
Pcmanbob very kindly helped me with this on the Ultrasonic sensors, see script below, I just want to replace the ultrasonic sensors with the data coming from the MCP3008 chip and I'm struggling to do this, I don't know what I'm doing wrong, please see pcmanbob's code below:

Code: Select all

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
from datetime import datetime
import os

# GPIO setup
GPIO.setmode (GPIO.BCM)
GPIO.setwarnings(False)

switch = 21
GPIO.setup(switch, GPIO.IN)

# setup gpio for echo & trig
echopin = [24,17,22,6,19,12,20]
trigpin = [23,4,27,5,13,25,16]
 
for j in range(7):
    GPIO.setup(trigpin[j], GPIO.OUT)
    GPIO.setup(echopin[j], GPIO.IN)
    print j, echopin[j], trigpin[j]
    print " "
    


# Get reading from HC-SR04   
def ping(echo, trig):
    
    GPIO.output(trig, False)
    # Allow module to settle
    time.sleep(0.5)
    # Send 10us pulse to trigger
    GPIO.output(trig, True)
    time.sleep(0.00001)
    GPIO.output(trig, False)
    pulse_start = time.time()

    # save StartTime
    while GPIO.input(echo) == 0:
        pulse_start = time.time()

    # save time of arrival
    while GPIO.input(echo) == 1:
        pulse_end = time.time()

    # time difference between start and arrival
    pulse_duration = pulse_end - pulse_start
    # mutiply with the sonic speed (34300 cm/s)
    # and divide by 2, because there and back
    distance = pulse_duration * 17150
    
    distance = round(distance, 2)
    
    return distance

print " press Ctrl+c to stop program "
try:
    # main loop
    while True:
         while GPIO.input(switch) == 0:
            time.sleep (0.5)
        # get distances and assemble data line for writing 
        results = str(datetime.now()) + ","
        for j in range(7):

            distance = ping(echopin[j], trigpin[j])
            print ("sensor", j+1,": ",distance,"cm")
            results = results + str(distance) + ","
            
        results = results + "\n"
              
        # write results data to file        
                      
        with open("/home/pi/data_log.csv", "a") as file:         
            if os.stat("/home/pi/data_log.csv").st_size == 0:
                file.write("Time,Sensor1,Sensor2,Sensor3,Sensor4,Sensor5,Sensor6,Sensor7\n")      
            file.write(results)
        # if sensors write to file to often increase this time        
        
        time.sleep (2)    
    
except KeyboardInterrupt:
    print("keyboard interrupt detected, File closed")       
    file.close()    
Hopefully this will help you understand what I'm looking for.

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Fri May 18, 2018 11:02 am
by Ghwana
I'm not very familiar with Python, its supposed to be the easiest code to write, but I'm trying to get my head around it, maybe I should have put this discussion in the beginner chat, not troubleshoot chat. :oops:

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Fri May 18, 2018 11:48 am
by scotty101
You need to take responsibility for your own learning.
Copy and Pasting other people's code will only get you so far. Python is easy but you won't find it easy if you try to jump in right at the deep end without first understanding the basics. Do you actually understand the code that you've been given?
The internet is full of python beginner tutorials, Follow one of those and learn about python. Once you've grasped the basics, the code that other people have posted will make more sense.
Sorry if that seems rude but this is your project.

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Fri May 18, 2018 12:10 pm
by Ghwana
Thank you for your support, appreciated.

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Fri May 18, 2018 6:27 pm
by pcmanbob
Here one way to build up your results line ready for writing to a csv file.

Code: Select all

# Main program loop.
while True:
    results = ""
    # 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] = readadc(i) + "n"
        
        results = results + values[i] + ","
 


You still need to sort out adding a new line at the end of all of the results and what ever header you want to use, but you should be able to work that out from my previous code example.

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Mon May 21, 2018 9:07 am
by Ghwana
Thank you much appreciated, will try that today. :)

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Mon May 21, 2018 10:26 am
by Ghwana
Hi, I've tried that and keeps getting this error, please see below:

Code: Select all

Python 2.7.13 (default, Nov 24 2017, 17:33:09) 
[GCC 6.3.0 20170516] on linux2
Type "copyright", "credits" or "license()" for more information.
>>> 
===================== RESTART: /home/pi/SmartShelfIR.py =====================
Reading MCP3008 values, press Ctrl-C to quit...
|    0 |    1 |    2 |    3 |    4 |    5 |    6 |    7 |
---------------------------------------------------------

Traceback (most recent call last):
  File "/home/pi/SmartShelfIR.py", line 50, in <module>
    results = results + values[i] + ","
TypeError: cannot concatenate 'str' and 'int' objects
>>> 

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Mon May 21, 2018 10:56 am
by Ghwana
It looks like I have resolved this, please see code below, the only problem now is the it only prints values on 1 line on spreadsheet over and over again, how do I get to print on different rows, columns are OK, prints on terminal perfectly and switch working perfectly. I must be missing something, I've checked everything.

Code: Select all

#!/usr/bin/python

import spidev
import RPi.GPIO as GPIO
import time
from datetime import datetime
import os

# GPIO setup
GPIO.setmode (GPIO.BCM)
GPIO.setwarnings(False)

switch = 18
GPIO.setup(switch, GPIO.IN)

#Define Variables
delay = 0.5


#Create SPI
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz=1000000

def readadc(adcnum):
    # read SPI data from the MCP3008, 8 channels in total
    if adcnum > 7 or adcnum < 0:
        return -1
    r = spi.xfer2([1, 8 + adcnum << 4, 0])
    data = ((r[1] & 3) << 8) + r[2]
    return data


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:
    while GPIO.input(switch) == 1:
        time.sleep (0.5)
        
    results = ""
    # 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] = readadc(i)

        results = results + str(values[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 one second.
    time.sleep(1)

    with open("/home/pi/data_log.csv", "a") as file:
            if os.stat("/home/pi/data_log.csv").st_size == 0:
                file.write("CH0,CH1,CH2,CH3,CH4,CH5,CH6,CH7\n")
            file.write(results)

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Mon May 21, 2018 11:25 am
by scotty101
Just add a new line after you've written the results.

Code: Select all

    with open("/home/pi/data_log.csv", "a") as file:
            if os.stat("/home/pi/data_log.csv").st_size == 0:
                file.write("CH0,CH1,CH2,CH3,CH4,CH5,CH6,CH7\n")
            file.write(results)
            file.write('\n')

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Mon May 21, 2018 11:28 am
by pcmanbob
I would have thought you would have worked this out for yourself as we did exactly the same in the other program I helped you with, and I did say you would need to add a new light character to the end of the results line ( hint may be ! )

So using exactly the same line as we used in the last program.

Code: Select all

        results = results + str(values[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 one second.
    time.sleep(1)

    results = results + "\n"
    
    with open("/home/pi/data_log.csv", "a") as file:
            if os.stat("/home/pi/data_log.csv").st_size == 0:
                file.write("CH0,CH1,CH2,CH3,CH4,CH5,CH6,CH7\n")
            file.write(results)
we add a new line to the end of the results line before writing it to the file, the same as we did before, which is why I was expecting you to be able to solve this for yourself. :(

Re: MCP 3008 Chip sending data to CSV file via switch

Posted: Mon May 21, 2018 11:34 am
by Ghwana
Hi, all resolved, it's slowly starting to sink in, here is the finished copy for anyone wanting to use this in the future, thanks to all who helped with the process, please see finished copy below. :)

Code: Select all

#!/usr/bin/python

import spidev
import RPi.GPIO as GPIO
import time
from datetime import datetime
import os

# GPIO setup
GPIO.setmode (GPIO.BCM)
GPIO.setwarnings(False)

switch = 18
GPIO.setup(switch, GPIO.IN)

#Define Variables
delay = 0.5


#Create SPI
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz=1000000

def readadc(adcnum):
    # read SPI data from the MCP3008, 8 channels in total
    if adcnum > 7 or adcnum < 0:
        return -1
    r = spi.xfer2([1, 8 + adcnum << 4, 0])
    data = ((r[1] & 3) << 8) + r[2]
    return data


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:
    while GPIO.input(switch) == 1:
        time.sleep (0.5)
        
    results = ""
    # 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] = readadc(i)

        results = results + str(values[i]) + ","

    results = results  + "\n"
        
    # 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 one second.
    time.sleep(1)

    with open("/home/pi/data_log.csv", "a") as file:
            if os.stat("/home/pi/data_log.csv").st_size == 0:
                file.write("CH0,CH1,CH2,CH3,CH4,CH5,CH6,CH7\n")
            file.write(results)
            time.sleep (0.5)