Ghwana
Posts: 70
Joined: Mon Nov 13, 2017 12:04 pm

MCP 3008 Chip sending data to CSV file via switch

Thu May 17, 2018 2:19 pm

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!

scotty101
Posts: 2987
Joined: Fri Jun 08, 2012 6:03 pm

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

Thu May 17, 2018 3:17 pm

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.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

pcmanbob
Posts: 4094
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

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

Thu May 17, 2018 6:12 pm

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.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

Ghwana
Posts: 70
Joined: Mon Nov 13, 2017 12:04 pm

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

Fri May 18, 2018 9:58 am

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.

scotty101
Posts: 2987
Joined: Fri Jun 08, 2012 6:03 pm

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

Fri May 18, 2018 10:15 am

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
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

scotty101
Posts: 2987
Joined: Fri Jun 08, 2012 6:03 pm

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

Fri May 18, 2018 10:23 am

Ghwana wrote:
Fri May 18, 2018 9:58 am
sent to csv through switch,
What does "through switch" mean?
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

Ghwana
Posts: 70
Joined: Mon Nov 13, 2017 12:04 pm

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

Fri May 18, 2018 10:28 am

Sorry, when switch is on data is sent to csv file, when switch is off, data stops being sent to csv file.

scotty101
Posts: 2987
Joined: Fri Jun 08, 2012 6:03 pm

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

Fri May 18, 2018 10:33 am

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:
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

Ghwana
Posts: 70
Joined: Mon Nov 13, 2017 12:04 pm

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

Fri May 18, 2018 10:36 am

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

Ghwana
Posts: 70
Joined: Mon Nov 13, 2017 12:04 pm

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

Fri May 18, 2018 10:41 am

It doesn't like values.

scotty101
Posts: 2987
Joined: Fri Jun 08, 2012 6:03 pm

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

Fri May 18, 2018 10:44 am

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.­
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

Ghwana
Posts: 70
Joined: Mon Nov 13, 2017 12:04 pm

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

Fri May 18, 2018 10:55 am

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.

Ghwana
Posts: 70
Joined: Mon Nov 13, 2017 12:04 pm

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

Fri May 18, 2018 11:02 am

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:

scotty101
Posts: 2987
Joined: Fri Jun 08, 2012 6:03 pm

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

Fri May 18, 2018 11:48 am

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.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

Ghwana
Posts: 70
Joined: Mon Nov 13, 2017 12:04 pm

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

Fri May 18, 2018 12:10 pm

Thank you for your support, appreciated.

pcmanbob
Posts: 4094
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

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

Fri May 18, 2018 6:27 pm

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.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

Ghwana
Posts: 70
Joined: Mon Nov 13, 2017 12:04 pm

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

Mon May 21, 2018 9:07 am

Thank you much appreciated, will try that today. :)

Ghwana
Posts: 70
Joined: Mon Nov 13, 2017 12:04 pm

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

Mon May 21, 2018 10:26 am

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
>>> 

Ghwana
Posts: 70
Joined: Mon Nov 13, 2017 12:04 pm

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

Mon May 21, 2018 10:56 am

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)

scotty101
Posts: 2987
Joined: Fri Jun 08, 2012 6:03 pm

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

Mon May 21, 2018 11:25 am

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')
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

pcmanbob
Posts: 4094
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

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

Mon May 21, 2018 11:28 am

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. :(
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

Ghwana
Posts: 70
Joined: Mon Nov 13, 2017 12:04 pm

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

Mon May 21, 2018 11:34 am

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)

Return to “Troubleshooting”

Who is online

Users browsing this forum: drgeoff, lmarmisa and 46 guests