Raccooooon
Posts: 14
Joined: Mon Feb 10, 2020 10:41 am

I just edit source to save written data to csv...

Thu Mar 26, 2020 6:53 am

I just edit source to save written data to csv...

but It's not working.

The Original code is from Sunfounder and I just add csv part.

How can I fix this problem?

Error is

Code: Select all

Traceback (most recent call last):
  File "17_adxl345.py", line 105, in <module>
    write_header = not os.path.exits(filename) or os.stat(filename).st_size == 0
AttributeError: module 'posixpath' has no attribute 'exits'

Code: Select all

from I2C import I2C
from time import sleep
import RPi.GPIO as GPIO
from sys import version_info
from datetime import datetime
import csv
import os

if version_info.major == 3:
raw_input = input

class ADXL345(I2C):

ADXL345_ADDRESS          = 0x53

ADXL345_REG_DEVID        = 0x00 # Device ID
ADXL345_REG_DATAX0       = 0x32 # X-axis data 0 (6 bytes for X/Y/Z)
ADXL345_REG_POWER_CTL    = 0x2D # Power-saving features control

ADXL345_DATARATE_0_10_HZ = 0x00
ADXL345_DATARATE_0_20_HZ = 0x01
ADXL345_DATARATE_0_39_HZ = 0x02
ADXL345_DATARATE_0_78_HZ = 0x03
ADXL345_DATARATE_1_56_HZ = 0x04
ADXL345_DATARATE_3_13_HZ = 0x05
ADXL345_DATARATE_6_25HZ  = 0x06
ADXL345_DATARATE_12_5_HZ = 0x07
ADXL345_DATARATE_25_HZ   = 0x08
ADXL345_DATARATE_50_HZ   = 0x09
ADXL345_DATARATE_100_HZ  = 0x0A # (default)
ADXL345_DATARATE_200_HZ  = 0x0B
ADXL345_DATARATE_400_HZ  = 0x0C
ADXL345_DATARATE_800_HZ  = 0x0D
ADXL345_DATARATE_1600_HZ = 0x0E
ADXL345_DATARATE_3200_HZ = 0x0F

ADXL345_RANGE_2_G        = 0x00 # +/-  2g (default)
ADXL345_RANGE_4_G        = 0x01 # +/-  4g
ADXL345_RANGE_8_G        = 0x02 # +/-  8g
ADXL345_RANGE_16_G       = 0x03 # +/- 16g

def __init__(self, busnum=-1, debug=False):
self.accel = I2C(self.ADXL345_ADDRESS, busnum, debug)
if self.accel.readU8(self.ADXL345_REG_DEVID) == 0xE5:
# Enable the accelerometer
self.accel.write8(self.ADXL345_REG_POWER_CTL, 0x08)

def setRange(self, range):
# Read the data format register to preserve bits.  Update the data
# rate, make sure that the FULL-RES bit is enabled for range scaling
format = ((self.accel.readU8(self.ADXL345_REG_DATA_FORMAT) & ~0x0F) |
 range | 0x08)
# Write the register back to the IC
seld.accel.write8(self.ADXL345_REG_DATA_FORMAT, format)

def getRange(self):
return self.accel.readU8(self.ADXL345_REG_DATA_FORMAT) & 0x03

def setDataRate(self, dataRate):
# Note: The LOW_POWER bits are currently ignored,
# we always keep the device in 'normal' mode
self.accel.write8(self.ADXL345_REG_BW_RATE, dataRate & 0x0F)

def getDataRate(self):
return self.accel.readU8(self.ADXL345_REG_BW_RATE) & 0x0F

# Read the accelerometer
def read(self):
raw = self.accel.readList(self.ADXL345_REG_DATAX0, 6)
#print (raw)
res = []
for i in range(0, 6, 2):
g = raw[i] | (raw[i+1] << 8)
g = 65535 - g
if g > 32767:
g -= 65535
res.append(g)
return res

def print_msg():
print ("========================================")
print ("|                ADXL345               |")
print ("|    ------------------------------    |")
print ("|          SCL connect to SCL          |")
print ("|          SDA connect to SDA          |")
print ("|                                      |")
print ("|        Read value from ADXL345       |")
print ("|                                      |")
print ("|                            SunFounder|")
print ("========================================\n")
print ("Program is running...")
print ("Please press Ctrl+C to end the program...")
raw_input ("Press anykey to begin\n")

# Simple example prints accelerometer data once per second:
def main():
accel = ADXL345()
while True:
x, y, z = accel.read()
print ("X: %d, Y: %d, Z: %d"%(x, y, z))
sleep(1) # Output is fun to watch if this is commented out

filename = "home/pi/logfiles/data_log.csv"
write_header = not os.path.exits(filename) or os.stat(filename).st_size == 0

with open(filename, "a", newline="") as f_output:
    csv_output = csv.writer(f_output)

    if write_header:
     csv.output.writerow(["Time", "Accel"])

    while True:
     row = [datetime.now().strftime("%Y-%m-%d %H:%M:%S"), x, y, z]
     csv_output.writerow(row)
     time.sleep(1)


def destroy():
exit()

if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
destroy()

markkuk
Posts: 174
Joined: Thu Mar 22, 2018 1:02 pm
Location: Finland

Re: I just edit source to save written data to csv...

Thu Mar 26, 2020 7:22 am

The call on line 105 should be os.path.exists(filename)

Raccooooon
Posts: 14
Joined: Mon Feb 10, 2020 10:41 am

Re: I just edit source to save written data to csv...

Thu Mar 26, 2020 8:20 am

Thanks for reply.
I solve this problem but, New error has appeared.

Code: Select all

File "17_adxl345.py", line114, in <module>
  row = [datetime.now().strftime("%Y-%m-%d %H:%M:%S"), x, y, z] 
NameError: name 'x' is not defined
but I thought X is already defined

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

Re: I just edit source to save written data to csv...

Thu Mar 26, 2020 8:48 am

Can you repost your source code?
The indentation has been lost from it so it is difficult to help you figure out why x doesn't exist in the context of line 114. Is line 114 inside the main function or is it not? I can't tell.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

Raccooooon
Posts: 14
Joined: Mon Feb 10, 2020 10:41 am

Re: I just edit source to save written data to csv...

Fri Mar 27, 2020 4:47 am

scotty101 wrote:
Thu Mar 26, 2020 8:48 am
Can you repost your source code?
The indentation has been lost from it so it is difficult to help you figure out why x doesn't exist in the context of line 114. Is line 114 inside the main function or is it not? I can't tell.
Thanks for help.

I tried to learn C++ and Python both. So, Maybe there is a mistake.

Code: Select all

from I2C import I2C
from time import sleep
import RPi.GPIO as GPIO
from sys import version_info
from datetime import datetime
import csv
import os

if version_info.major == 3:
raw_input = input

class ADXL345(I2C):

ADXL345_ADDRESS          = 0x53

ADXL345_REG_DEVID        = 0x00 # Device ID
ADXL345_REG_DATAX0       = 0x32 # X-axis data 0 (6 bytes for X/Y/Z)
ADXL345_REG_POWER_CTL    = 0x2D # Power-saving features control

ADXL345_DATARATE_0_10_HZ = 0x00
ADXL345_DATARATE_0_20_HZ = 0x01
ADXL345_DATARATE_0_39_HZ = 0x02
ADXL345_DATARATE_0_78_HZ = 0x03
ADXL345_DATARATE_1_56_HZ = 0x04
ADXL345_DATARATE_3_13_HZ = 0x05
ADXL345_DATARATE_6_25HZ  = 0x06
ADXL345_DATARATE_12_5_HZ = 0x07
ADXL345_DATARATE_25_HZ   = 0x08
ADXL345_DATARATE_50_HZ   = 0x09
ADXL345_DATARATE_100_HZ  = 0x0A # (default)
ADXL345_DATARATE_200_HZ  = 0x0B
ADXL345_DATARATE_400_HZ  = 0x0C
ADXL345_DATARATE_800_HZ  = 0x0D
ADXL345_DATARATE_1600_HZ = 0x0E
ADXL345_DATARATE_3200_HZ = 0x0F

ADXL345_RANGE_2_G        = 0x00 # +/-  2g (default)
ADXL345_RANGE_4_G        = 0x01 # +/-  4g
ADXL345_RANGE_8_G        = 0x02 # +/-  8g
ADXL345_RANGE_16_G       = 0x03 # +/- 16g

def __init__(self, busnum=-1, debug=False):
self.accel = I2C(self.ADXL345_ADDRESS, busnum, debug)
if self.accel.readU8(self.ADXL345_REG_DEVID) == 0xE5:
# Enable the accelerometer
self.accel.write8(self.ADXL345_REG_POWER_CTL, 0x08)

def setRange(self, range):
# Read the data format register to preserve bits.  Update the data
# rate, make sure that the FULL-RES bit is enabled for range scaling
format = ((self.accel.readU8(self.ADXL345_REG_DATA_FORMAT) & ~0x0F) |
 range | 0x08)
# Write the register back to the IC
seld.accel.write8(self.ADXL345_REG_DATA_FORMAT, format)

def getRange(self):
return self.accel.readU8(self.ADXL345_REG_DATA_FORMAT) & 0x03

def setDataRate(self, dataRate):
# Note: The LOW_POWER bits are currently ignored,
# we always keep the device in 'normal' mode
self.accel.write8(self.ADXL345_REG_BW_RATE, dataRate & 0x0F)

def getDataRate(self):
return self.accel.readU8(self.ADXL345_REG_BW_RATE) & 0x0F

# Read the accelerometer
def read(self):
raw = self.accel.readList(self.ADXL345_REG_DATAX0, 6)
#print (raw)
res = []
for i in range(0, 6, 2):
g = raw[i] | (raw[i+1] << 8)
g = 65535 - g
if g > 32767:
g -= 65535
res.append(g)
return res

def print_msg():
print ("========================================")
print ("|                ADXL345               |")
print ("|    ------------------------------    |")
print ("|          SCL connect to SCL          |")
print ("|          SDA connect to SDA          |")
print ("|                                      |")
print ("|        Read value from ADXL345       |")
print ("|                                      |")
print ("|                            SunFounder|")
print ("========================================\n")
print ("Program is running...")
print ("Please press Ctrl+C to end the program...")
raw_input ("Press anykey to begin\n")

# Simple example prints accelerometer data once per second:
def main():
accel = ADXL345()
while True:
x, y, z = accel.read()
print ("X: %d, Y: %d, Z: %d"%(x, y, z))
sleep(1) # Output is fun to watch if this is commented out

filename = "home/pi/logfiles/data_log.csv"
write_header = not os.path.exists(filename) or os.stat(filename).st_size == 0

with open(filename, "a", newline="") as f_output:
    csv_output = csv.writer(f_output)

    if write_header:
     csv.output.writerow(["Time", "Accel"])

    while True:
     row = [datetime.now().strftime("%Y-%m-%d %H:%M:%S"), x, y, z]
     csv_output.writerow(row)
     time.sleep(1)


def destroy():
exit()

if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
destroy()

markkuk
Posts: 174
Joined: Thu Mar 22, 2018 1:02 pm
Location: Finland

Re: I just edit source to save written data to csv...

Fri Mar 27, 2020 8:20 am

Indentations are significant in Python code. If the code you posted really matches what you have on your computer, then it's completely broken. All the functions, conditional statements and loops are missing indentations for their bodies. Only the "with" statement near the end appears correct.

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

Re: I just edit source to save written data to csv...

Fri Mar 27, 2020 9:03 am

As markkuk said, python relies on indentation and your code is seriously missing it.

Code: Select all

def main():
print("Hello")
is not the same as

Code: Select all

def main():
    print("Hello")
In the second example the print statement is part of the function main.

Unlike C++ there is no use of braces {} to indicate the start/end of sections of code so you must correctly indent.

Basic rule that I teach to the 10 year olds at code club, if you have a colon : generally speaking the next line should be indented a further 4 spaces.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

Return to “Python”