First one:
### configuration details
TELEGRAM_TOKEN = '' # telegram bot token
TELEGRAM_CHANNEL ='' # channel id
INTERVAL = '1m' # binance time interval
SHORT_EMA = 7 # short interval for ema
LONG_EMA = 21 # long interval for ema
Here is my second code:
import requests
import talib
import time
import numpy as np
import websocket
from config import TELEGRAM_TOKEN, TELEGRAM_CHANNEL , INTERVAL, SHORT_EMA , LONG_EMA
def streamKline(currency, interval):
websocket.enableTrace(False)
socket = f'wss://stream.binance.com:9443/ws/{currency}#kline_{interval}'
ws = websocket.WebSocketApp(socket)
ws.run_forever()
#SYMBOLS TO LOOK FOR ALERTS
SYMBOLS = [
"ETHUSDT",
"BTCUSDT",
"ATOMUSDT",
"BNBUSDT",
"FTMBUSD",
"ENJUSDT",
"WAXPUSDT"
]
#sending alerts to telegram
def send_message(message):
url = "https://api.telegram.org/bot{}/sendMessage?chat_id={}&text={}&parse_mode=markdown".format(TELEGRAM_TOKEN,TELEGRAM_CHANNEL,message)
res = requests.get(url);print(url);
return res
# getting klines data to process
def streamKline(symbol):
data = socket.streamKline(symbol=symbol,interval=INTERVAL,limit=300) # more data means more precision but at the trade off between speed and time
return_data = []
# taking closing data for each kline
for each in data:
return_data.append(float(each[4])) # 4 is the index of the closing data in each kline
return np.array(return_data) # returning as numpy array for better precision and performance
def main():
# making a infinite loop that keeps checking for condition
while True:
#looping through each coin
for each in SYMBOLS:
data = streamKline(each)
ema_short = talib.EMA(data,int(SHORT_EMA))
ema_long = talib.EMA(data,int(LONG_EMA))
last_ema_short = ema_short[-2]
last_ema_long = ema_long[-2]
ema_short = ema_short[-1]
ema_long = ema_long[-1]
# conditions for alerts
if(ema_short > ema_long and last_ema_short < last_ema_long):
message = each + "bullcoming "+ str(SHORT_EMA) + " over "+str(LONG_EMA);print(each ,"alert came");
send_message(message);
time.sleep(0.5);
# calling the function
if __name__ == "__main__":
main()
The part of config is all settle done, just second for the kline data, the error mention lot like this.
data = socket.streamKline(symbol=symbol,interval=INTERVAL,limit=300) # more data means more precision but at the
trade off between speed and time
NameError: name 'socket' is not defined
I just don't know how to do it, I want build a ema alert that can give me a message when I am not watching chart, through this way seems not work, I have tried many times, and also find many video but still, I am just an beginner, nothing improving at all.
Need some help to set the configuration for sasl.mechanism PLAIN (API) and GSSAPI (Kerberos) authentication.
We are using confluent Kafka here, there are two scripts, one a python script and the second one is a bash script which calls the python one. You can find the script below.
Thanks for the help in advance!
import json
import os
import string
import random
import socket
import uuid
import re
from datetime import datetime
import time
import hashlib
import math
import sys
from functools import cache
from confluent_kafka import Producer, KafkaError, KafkaException
topic_name = os.environ['TOPIC_NAME']
partition_count = int(os.environ['PARTITION_COUNT'])
message_key_template = json.loads(os.environ['KEY_TEMPLATE'])
message_value_template = json.loads(os.environ['VALUE_TEMPLATE'])
message_header_template = json.loads(os.environ['HEADER_TEMPLATE'])
bootstrap_servers = os.environ['BOOTSTRAP_SERVERS']
perf_counter_batch_size = int(os.environ.get('PERF_COUNTER_BATCH_SIZE', 100))
messages_per_aggregate = int(os.environ.get('MESSAGES_PER_AGGREGATE', 1))
max_message_count = int(os.environ.get('MAX_MESSAGE_COUNT', sys.maxsize))
def error_cb(err):
""" The error callback is used for generic client errors. These
errors are generally to be considered informational as the client will
automatically try to recover from all errors, and no extra action
is typically required by the application.
For this example however, we terminate the application if the client
is unable to connect to any broker (_ALL_BROKERS_DOWN) and on
authentication errors (_AUTHENTICATION). """
print("Client error: {}".format(err))
if err.code() == KafkaError._ALL_BROKERS_DOWN or \
err.code() == KafkaError._AUTHENTICATION:
# Any exception raised from this callback will be re-raised from the
# triggering flush() or poll() call.
raise KafkaException(err)
def acked(err, msg):
if err is not None:
print("Failed to send message: %s: %s" % (str(msg), str(err)))
producer_configs = {
'bootstrap.servers': bootstrap_servers,
'client.id': socket.gethostname(),
'error_cb': error_cb
}
# TODO: Need to support sasl.mechanism PLAIN (API) and GSSAPI (Kerberos) authentication.
# TODO: Need to support truststores for connecting to private DCs.
producer = Producer(producer_configs)
# generates a random value if it is not cached in the template_values dictionary
def get_templated_value(term, template_values):
if not term in template_values:
template_values[term] = str(uuid.uuid4())
return template_values[term]
def fill_template_value(value, template_values):
str_value = str(value)
template_regex = '{{(.+?)}}'
templated_terms = re.findall(template_regex, str_value)
for term in templated_terms:
str_value = str_value.replace(f"{{{{{term}}}}}", get_templated_value(term, template_values))
return str_value
def fill_template(template, templated_terms):
# TODO: Need to address metadata field, as it's treated as a string instead of a nested object.
return {field: fill_template_value(value, templated_terms) for field, value in template.items()}
#cache
def get_partition(lock_id):
bits = 128
bucket_size = 2**bits / partition_count
partition = (int(hashlib.md5(lock_id.encode('utf-8')).hexdigest(), 16) / bucket_size)
return math.floor(partition)
sequence_number = int(time.time() * 1000)
sequence_number = 0
message_count = 0
producing = True
start_time = time.perf_counter()
aggregate_message_counter = 0
# cache for templated term values so that they match across the different templates
templated_values = {}
try:
while producing:
sequence_number += 1
aggregate_message_counter += 1
message_count += 1
if aggregate_message_counter % messages_per_aggregate == 0:
# reset templated values
templated_values = {}
else:
for term in list(templated_values):
if term not in ['aggregateId', 'tenantId']:
del(templated_values[term])
# Fill in templated field values
message_key = fill_template(message_key_template, templated_values)
message_value = fill_template(message_value_template, templated_values)
message_header = fill_template(message_header_template, templated_values)
ts = datetime.utcnow().isoformat()[:-3]+'Z'
message_header['timestamp'] = ts
message_header['sequence_number'] = str(sequence_number)
message_value['timestamp'] = ts
message_value['sequenceNumber'] = sequence_number
lock_id = message_header['lock_id']
partition = get_partition(lock_id) # partition by lock_id, since key could be random, but a given aggregate_id should ALWAYS resolve to the same partition, regardless of key.
# Send message
producer.produce(topic_name, partition=partition, key=json.dumps(message_key), value=json.dumps(message_value), headers=message_header, callback=acked)
if sequence_number % perf_counter_batch_size == 0:
producer.flush()
end_time = time.perf_counter()
total_duration = end_time - start_time
messages_per_second=(perf_counter_batch_size/total_duration)
print(f'{messages_per_second} messages/second')
# reset start time
start_time = time.perf_counter()
if message_count >= max_message_count:
break
except Exception as e:
print(f'ERROR: %s' % e)
sys.exit(1)
finally:
producer.flush()
I am currently working working on a program that tries to replicate labview functionality by establishing a connection to SR830 via RS-232. For some reasons, I am not able to record data and I cannot seem to figure out why. I tried to google about it but I did not find anything. If someone could please help me figure out what I am doing wrong.
Here is my code:
import serial
import tkinter as tk
from datetime import datetime
import time
import os
import atexit
import threading
import numpy as np
import math
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import matplotlib.animation as animation
class SR830:
'''SR830 Class creates an object that can interface with and control an SR830 via RS-232.
Class data structure allows the SR830 code to be imported into other scripts via "from SSTR_Serial import SR830"
This can be used to encapsulate SR830 interface mechanics into a larger control scheme...
by passing the class a frame to pack itself into as the frame argument.'''
def command(self, command_string, command_value): #Basic command protocol, can be used as a template for other command functions.
#Note: queries should have null command_value arguments (command_value = '').
packet = command_string+str(command_value)+'\r' #Can be adjusted to include checksums/parity if needed.
try:
self.inst.write(packet.encode('ascii'))
except AttributeError as AE:
print(AE)
def create_log(self):
try: #Makes log file if it does not exist already.
log_dir = self.name+'_logs'
os.mkdir(log_dir)
except OSError:#Log file already exists
pass
self.log_open = datetime.now() #Var to hold time log was created (Different from when timer is started.)
date = str(self.log_open).split(' ')[0] #Date that log file was opened.
h = 0
a = False
while not a:
h += 1
log_str = log_dir+'/'+self.name+"_"+date+'_'+str(h)+'.txt'
log_path = os.path.join(os.getcwd(), log_str)
if os.path.exists(log_path):
pass
else:
a = True
self.log = open(log_str, "w+")
self.log.write(self.name+" log created on "+ str(self.log_open)+"\nTime \tShift (Degrees)\tAmplitude (mV)\tR ()\tTheta ()\n") #Writing opening lines.
def start_graph(self): #Should be threaded at begining. This begins making the graph and recording data when the start/record buttons are pressed.
def get_vals(self):
current_time = time.time()#Get current time
if (current_time - self.previous_time) >= self.sample_time: #Time is equal or passed sampling time.
time_elapsed = current_time - self.start_time #Total time elapsed since transmission begun.
#Transmission zone:
try: #Querying and storing commands below
self.command("PHAS?",'')
phase_shift = self.inst.read(5).decode('ascii').replace('\r','')
self.command('SLVL?','')
phase_amplitude = self.inst.read(5).decode('ascii').replace('\r','')
self.shifts = np.append(self.shifts,[phase_shift]); self.amplitudes = np.append(self.amplitudes,[phase_amplitude]); self.times = np.append(self.times,[time_elapsed]) #Will only append time if both other arrays are appended.
#^ Append on one line to keep all lengths consistant when switching threads.
#Variables that are queried but not logged.
self.command('OEXP?1','')
R = self.inst.read(5).decode('ascii').replace('\r','')
self.command('OEXP?2','')
Theta = self.inst.read(5).decode('ascii').replace('\r','')
except AttributeError as AE:#Exceptions for testing without connection to device
print(AE)
'''
#This area generates random sine waves. Only use for testing without connection to actual device.---------
self.times = np.append(self.times,[len(self.times)])
self.shifts = np.append(self.shifts,[math.sin(len(self.times))])
self.amplitudes = np.append(self.amplitudes, [5*math.cos(len(self.times))])
phase_shift = 5
phase_amplitude = 7
R = 10
Theta = 11
print(str(len(self.times)))
print(str(len(self.shifts)))
print(str(len(self.amplitudes)))
#End test zone ---------------------------------------------------------------------------------------
'''
#Remove extra elements to reduce memeory usage for long runs
while len(self.times) > 200: #Integer on RHS of inequality is max number of elements.
self.shifts = self.shifts[2:-1:1]; self.amplitudes = self.amplitudes[2:-1:1]; self.times=self.times[2:-1:1]
#Log writing zone:
if self.recording is True: #Updates log, otherwise only updates graph.
self.log.write(str(round(time_elapsed-self.pause_time,4))+'\t'+str(phase_shift)+'\t\t'+str(phase_amplitude)+'\t\t'+str(R)+'\t'+str(Theta)+'\n')
self.previous_time = current_time #Resets time value for calculating interval.
while self.running: #Loops as long as running is true and kills thread once runing is false.
get_vals(self)
def animate(self, i): #Only redraw matplotlib aspects that get cleared with a.clear() and a2.clear() to conserve memory.
#Todo - optimize drawing order
try:
self.a.clear()
self.a.plot(self.times,self.shifts, label='Phase shift ()', color='tab:blue')
self.a.set_ylabel('Shift')
self.a.set_ylabel('Shift', color='tab:blue')
self.a.set_xlabel('Time (s)')
self.a.legend(loc='upper left')
self.a2.clear()
self.a2.plot(self.times,self.amplitudes,label='Phase amplitude ()',color='tab:red')
self.a2.set_ylabel('Amplitude', color='tab:red')
self.a2.legend(loc='upper right')
self.a.get_yaxis_transform()#Fits axis to widget area.
except ValueError as VE:
print(VE)
def clear_graph(self): #Clears all arrays to make graph reset. Does not erase logged data.
self.times = np.array([])
self.shifts = np.array([])
self.amplitudes = np.array([])
def startstop(self): #Flips button to begin or stop graphing.
if self.running is False: #Recording and graphing is off. Calling function will turn it on and activate the following lines
self.running = True
self.clear_graph() #Clears last run.
self.run_btn.config(text='Stop', bg='red')
#self.start_graph()
self.sample_time = float(self.sample_box.get())
self.pause_time = 0 #Resets pause adjustment time.
self.start_time = time.time() #Resets start time. TODO-Add adjustments for pauses
self.pause_point = time.time() #Last time that pause activated. Used to calculate pause_time later.
self.graph_thread = threading.Thread(target=self.start_graph)
self.graph_thread.start()
else: #graphing is on. Calling function will turn it off and activate the following line
self.running = False
self.run_btn.config(text='Start',bg='green')
self.recording=False
self.record_btn.config(text='Start recording', bg="green")
try: #Shuts down log file if it exists.
self.log.close()
except AttributeError as AE:
print(AE)
def startstop_record(self): #Flips recording button.
if self.running is False:
self.startstop() #Makes sure data is being transmitted before recording starts.
if self.recording is False: #Device is running, but not recording. Command turns recording on.
self.record_btn.config(text='Pause recording', bg="yellow")
try:
self.log.write('') #Attempts to write an empty string to test if file is open.
except AttributeError: #File has not been created -> run function to open a new log.
self.create_log()
except ValueError: #Previous log file has been closed -> run function to open new log.
self.create_log()
self.recording = True
self.pause_time += time.time() - self.pause_point #Adjusts for
else: #Device is running AND recording. Command pauses recording.
self.recording = False
self.pause_point = time.time()
self.record_btn.config(text='Start recording', bg="green")
def __init__(self, name, frame):
self.name = name
self.running = False
self.recording = False
#Read config -----------------------------------------------------------------------
config = open('SR830 config.txt','w+')
try:
config_read = config.readlines()
config_read = config_read[1].split('\t')
except IndexError: #config coudl not be read - creates default file.
config.write('COM Baudrate\ttimeout\tsampling time\n10\t9600\t0.1\t1')
config.close()
config = open('SR830 config.txt','r')
config_read = config.readlines()
config_read = config_read[1].split('\t')
com = config_read[0]
baud = int(config_read[1])
self.config_timeout = float(config_read[2])
self.sample_time = float(config_read[3])
config.close()
#establish communication -----------------------------------------------------------
com = 'COM'+str(com) #TODO- make this read from config
try:
SR_inst = serial.Serial(port=com, baudrate=baud, timeout=self.config_timeout) #Opens communication.
#Note: SR830 has adjustablebaud rate and parity, but defaults to 9600 and none, respectively.
self.inst = SR_inst
self.command('OUTX',0) #Tells device to output responses via RS-232.
print(self.inst.read(5)) #Prints response to OUTX command.
#self.command('OUTX?','') #TEST - see if communication has switched.
#print(self.inst.read(10)) #Should print b'0\r' for RS-232 communication.
self.command('DDEF',110)#Sets CH1 to R.
print(self.inst.read(5))
self.command('DDEF',210)#Sets CH2 to Theta.
print(self.inst.read(5))
except ValueError as ve:
SR_inst = 0
print(ve)
except AttributeError as ae:
SR_inst = 0
print (ae)
except NameError as ne:
print(ne)
SR_inst = 0
except serial.SerialException as SE:
SR_inst = 0
print(SE)
#Create Tkinter GUI------------------------------------------------------------------
id_label=tk.Label(frame, text=name)
id_label.grid(row=0,column=0, sticky=tk.N+tk.S+tk.E+tk.W)
version_label = tk.Label(frame, text = 'Version 0.1')
version_label.grid(row=0, column=1, sticky=tk.N+tk.S+tk.E+tk.W)
sample_label = tk.Label(frame, text="Sampling time =")
sample_label.grid(row=1,column=0,sticky=tk.N+tk.S+tk.E+tk.W)
self.sample_box = tk.Entry(frame)
self.sample_box.insert(tk.END, self.sample_time)
self.sample_box.grid(row=1,column=1,sticky=tk.N+tk.S+tk.E+tk.W)
self.run_btn = tk.Button(frame, text='Start', command = self.startstop)
self.run_btn.grid(row=2,column=0,sticky=tk.N+tk.S+tk.E+tk.W)
self.run_btn.config(bg="green")
self.record_btn = tk.Button(frame, text='Start recording', command = self.startstop_record)
self.record_btn.grid(row=2,column=1,sticky=tk.N+tk.S+tk.E+tk.W)
self.record_btn.config(bg="green")
#Graph setup:
self.f = Figure(figsize=(5,5),dpi=100) #Figure that graphs appears in
self.a = self.f.add_subplot() #111 means there is only 1 chart. use a.plot to plot lists.
self.a2 = self.a.twinx()
self.graph_canvas = FigureCanvasTkAgg(self.f, frame)
self.graph_canvas.get_tk_widget().grid(row=3, column=0,columnspan=2)
#Make grid resizeable
for row in range(4): #Number of rows
try:
tk.Grid.rowconfigure(frame,row,weight=2)
except AttributeError as AE: #FOr unfilled rows & columns
print(AE)
for column in range(2): #Number of columns
try:
#root.grid_columnconfigure(column, weight=1)
tk.Grid.columnconfigure(frame,column,weight=1)
except AttributeError as AE: #For unfilled rows & columns
print(AE)
#Extra declarations
self.sample_time = float(self.sample_box.get())-2*self.config_timeout #Adjusts for timeout of device.
self.times = np.array([]) #Holds time values queried (May not be recorded)
self.shifts = np.array([])#Holds shift values queried.
self.amplitudes = np.array([])#Holds amplitude values queried.
#self.start_time = time.time() #TODO - Move this somewhere better
self.previous_time = 0
time.sleep(1)
self.ani = animation.FuncAnimation(self.f,self.animate, interval=1000)
def SR830_exit(self): #Exit handler.
self.running = False
self.recording = False
try:
self.inst.close()
except AttributeError as AE:
print(AE)
root.destroy()
exit()
#TEST AREA: ------------------------------------------------------------------------------
# Create tk root -------------------
root = tk.Tk()
root.title('SR830')
frame1 = tk.Frame(root)
frame1.pack()
#Create instrument object ---------
sr1 = SR830("SSTR", frame1) #TODO - remove once testing is done.
atexit.register(sr1.SR830_exit)
root.protocol('WM_DELETE_WINDOW', sr1.SR830_exit)
root.mainloop()
Good days, I'm new to python and trying to run a demo provided by Invensense.(9-axis MPU9250 connects a STM32F407G discovery board, I used code and python client in motion_driver_6.12 which downloaded from Invensense website.)
the whole python part are python2.7, pysearil, pygame.
I searched my issues in Stackoverflow, but the specific situations are a little different, and most of the solutions are useless for me.
First, I show my issues.
UART connects the PC, run Invensense's python client through cmd.exe, pygame window appears briefly and disappear and I get the following error
D:\motion_driver_6.12\eMPL-pythonclient>python eMPL-client.py 7
Traceback (most recent call last):
File "eMPL-client.py", line 273, in <module>
def four_bytes(d1, d2, d3, d4):
File "eMPL-client.py", line 12, in __init__
File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 31, in
__init__
super(Serial, self).__init__(*args, **kwargs)
File "C:\Python27\lib\site-packages\serial\serialutil.py", line 218, in
__init__
self.port = port
File "C:\Python27\lib\site-packages\serial\serialutil.py", line 264, in port
raise ValueError('"port" must be None or a string, not
{}'.format(type(port)))
ValueError: "port" must be None or a string, not <type 'int'>
Second, through the similar questions, what I have done until now:
open the file "serialwin32.py" .Change port = self.name to port = str(self.name). It doesn't work, same error messages.
uninstall the pyserial3.3(the lastest version), using a pyserial2.7. The error meesages were gone but Pygmae now just sits there with a black screen.The old answer said "Invensense tells me that means it is connected and waiting for data".
----------------followed is eMPL-client.py, line 21 and line 273 are marked-----
#!/usr/bin/python
# eMPL_client.py
# A PC application for use with Embedded MotionApps.
# Copyright 2012 InvenSense, Inc. All Rights Reserved.
import serial, sys, time, string, pygame
from ponycube import *
class eMPL_packet_reader:
//*********************line 21 __init__ begins********************//
def __init__(self, port, quat_delegate=None, debug_delegate=None, data_delegate=None ):
self.s = serial.Serial(port,115200)
self.s.setTimeout(0.1)
self.s.setWriteTimeout(0.2)
# TODO: Will this break anything?
##Client attempts to write to eMPL.
#try:
#self.s.write("\n")
#except serial.serialutil.SerialTimeoutException:
#pass # write will timeout if umpl app is already started.
if quat_delegate:
self.quat_delegate = quat_delegate
else:
self.quat_delegate = empty_packet_delegate()
if debug_delegate:
self.debug_delegate = debug_delegate
else:
self.debug_delegate = empty_packet_delegate()
if data_delegate:
self.data_delegate = data_delegate
else:
self.data_delegate = empty_packet_delegate()
self.packets = []
self.length = 0
self.previous = None
def read(self):
NUM_BYTES = 23
p = None
while self.s.inWaiting() >= NUM_BYTES:
rs = self.s.read(NUM_BYTES)
if ord(rs[0]) == ord('$'):
pkt_code = ord(rs[1])
if pkt_code == 1:
d = debug_packet(rs)
self.debug_delegate.dispatch(d)
elif pkt_code == 2:
p = quat_packet(rs)
self.quat_delegate.dispatch(p)
elif pkt_code == 3:
d = data_packet(rs)
self.data_delegate.dispatch(d)
else:
print "no handler for pkt_code",pkt_code
else:
c = ' '
print "serial misaligned!"
while not ord(c) == ord('$'):
c = self.s.read(1)
self.s.read(NUM_BYTES-1)
def write(self,a):
self.s.write(a)
def close(self):
self.s.close()
def write_log(self,fname):
f = open(fname,'w')
for p in self.packets:
f.write(p.logfile_line())
f.close()
# =========== PACKET DELEGATES ==========
class packet_delegate(object):
def loop(self,event):
print "generic packet_delegate loop w/event",event
def dispatch(self,p):
print "generic packet_delegate dispatched",p
class empty_packet_delegate(packet_delegate):
def loop(self,event):
pass
def dispatch(self,p):
pass
class cube_packet_viewer (packet_delegate):
def __init__(self):
self.screen = Screen(480,400,scale=1.5)
self.cube = Cube(30,60,10)
self.q = Quaternion(1,0,0,0)
self.previous = None # previous quaternion
self.latest = None # latest packet (get in dispatch, use in loop)
def loop(self,event):
packet = self.latest
if packet:
q = packet.to_q().normalized()
self.cube.erase(self.screen)
self.cube.draw(self.screen,q)
pygame.display.flip()
self.latest = None
def dispatch(self,p):
if isinstance(p,quat_packet):
self.latest = p
class debug_packet_viewer (packet_delegate):
def loop(self,event):
pass
def dispatch(self,p):
assert isinstance(p,debug_packet);
p.display()
class data_packet_viewer (packet_delegate):
def loop(self,event):
pass
def dispatch(self,p):
assert isinstance(p,data_packet);
p.display()
# =============== PACKETS =================
# For 16-bit signed integers.
def two_bytes(d1,d2):
d = ord(d1)*256 + ord(d2)
if d > 32767:
d -= 65536
return d
# For 32-bit signed integers.
//**************************273 begins*********************************//
def four_bytes(d1, d2, d3, d4):
d = ord(d1)*(1<<24) + ord(d2)*(1<<16) + ord(d3)*(1<<8) + ord(d4)
if d > 2147483648:
d-= 4294967296
return d
----------------followed is serialutil.py(version 3.3) from line1 to line272, 218 and 264 are marked-------------
#! python
#
# Base class and support functions used by various backends.
#
# This file is part of pySerial. https://github.com/pyserial/pyserial
# (C) 2001-2016 Chris Liechti <cliechti#gmx.net>
#
# SPDX-License-Identifier: BSD-3-Clause
import io
import time
# ``memoryview`` was introduced in Python 2.7 and ``bytes(some_memoryview)``
# isn't returning the contents (very unfortunate). Therefore we need special
# cases and test for it. Ensure that there is a ``memoryview`` object for older
# Python versions. This is easier than making every test dependent on its
# existence.
try:
memoryview
except (NameError, AttributeError):
# implementation does not matter as we do not really use it.
# it just must not inherit from something else we might care for.
class memoryview(object): # pylint: disable=redefined-builtin,invalid-name
pass
try:
unicode
except (NameError, AttributeError):
unicode = str # for Python 3, pylint: disable=redefined-builtin,invalid-name
try:
basestring
except (NameError, AttributeError):
basestring = (str,) # for Python 3, pylint: disable=redefined-builtin,invalid-name
# "for byte in data" fails for python3 as it returns ints instead of bytes
def iterbytes(b):
"""Iterate over bytes, returning bytes instead of ints (python3)"""
if isinstance(b, memoryview):
b = b.tobytes()
i = 0
while True:
a = b[i:i + 1]
i += 1
if a:
yield a
else:
break
# all Python versions prior 3.x convert ``str([17])`` to '[17]' instead of '\x11'
# so a simple ``bytes(sequence)`` doesn't work for all versions
def to_bytes(seq):
"""convert a sequence to a bytes type"""
if isinstance(seq, bytes):
return seq
elif isinstance(seq, bytearray):
return bytes(seq)
elif isinstance(seq, memoryview):
return seq.tobytes()
elif isinstance(seq, unicode):
raise TypeError('unicode strings are not supported, please encode to bytes: {!r}'.format(seq))
else:
# handle list of integers and bytes (one or more items) for Python 2 and 3
return bytes(bytearray(seq))
# create control bytes
XON = to_bytes([17])
XOFF = to_bytes([19])
CR = to_bytes([13])
LF = to_bytes([10])
PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE = 'N', 'E', 'O', 'M', 'S'
STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO = (1, 1.5, 2)
FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5, 6, 7, 8)
PARITY_NAMES = {
PARITY_NONE: 'None',
PARITY_EVEN: 'Even',
PARITY_ODD: 'Odd',
PARITY_MARK: 'Mark',
PARITY_SPACE: 'Space',
}
class SerialException(IOError):
"""Base class for serial port related exceptions."""
class SerialTimeoutException(SerialException):
"""Write timeouts give an exception"""
writeTimeoutError = SerialTimeoutException('Write timeout')
portNotOpenError = SerialException('Attempting to use a port that is not open')
class Timeout(object):
"""\
Abstraction for timeout operations. Using time.monotonic() if available
or time.time() in all other cases.
The class can also be initialized with 0 or None, in order to support
non-blocking and fully blocking I/O operations. The attributes
is_non_blocking and is_infinite are set accordingly.
"""
if hasattr(time, 'monotonic'):
# Timeout implementation with time.monotonic(). This function is only
# supported by Python 3.3 and above. It returns a time in seconds
# (float) just as time.time(), but is not affected by system clock
# adjustments.
TIME = time.monotonic
else:
# Timeout implementation with time.time(). This is compatible with all
# Python versions but has issues if the clock is adjusted while the
# timeout is running.
TIME = time.time
def __init__(self, duration):
"""Initialize a timeout with given duration"""
self.is_infinite = (duration is None)
self.is_non_blocking = (duration == 0)
self.duration = duration
if duration is not None:
self.target_time = self.TIME() + duration
else:
self.target_time = None
def expired(self):
"""Return a boolean, telling if the timeout has expired"""
return self.target_time is not None and self.time_left() <= 0
def time_left(self):
"""Return how many seconds are left until the timeout expires"""
if self.is_non_blocking:
return 0
elif self.is_infinite:
return None
else:
delta = self.target_time - self.TIME()
if delta > self.duration:
# clock jumped, recalculate
self.target_time = self.TIME() + self.duration
return self.duration
else:
return max(0, delta)
def restart(self, duration):
"""\
Restart a timeout, only supported if a timeout was already set up
before.
"""
self.duration = duration
self.target_time = self.TIME() + duration
class SerialBase(io.RawIOBase):
"""\
Serial port base class. Provides __init__ function and properties to
get/set port settings.
"""
# default values, may be overridden in subclasses that do not support all values
BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000,
576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000,
3000000, 3500000, 4000000)
BYTESIZES = (FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS)
PARITIES = (PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE)
STOPBITS = (STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO)
def __init__(self,
port=None,
baudrate=9600,
bytesize=EIGHTBITS,
parity=PARITY_NONE,
stopbits=STOPBITS_ONE,
timeout=None,
xonxoff=False,
rtscts=False,
write_timeout=None,
dsrdtr=False,
inter_byte_timeout=None,
exclusive=None,
**kwargs):
"""\
Initialize comm port object. If a "port" is given, then the port will be
opened immediately. Otherwise a Serial port object in closed state
is returned.
"""
self.is_open = False
self.portstr = None
self.name = None
# correct values are assigned below through properties
self._port = None
self._baudrate = None
self._bytesize = None
self._parity = None
self._stopbits = None
self._timeout = None
self._write_timeout = None
self._xonxoff = None
self._rtscts = None
self._dsrdtr = None
self._inter_byte_timeout = None
self._rs485_mode = None # disabled by default
self._rts_state = True
self._dtr_state = True
self._break_state = False
self._exclusive = None
# assign values using get/set methods using the properties feature
//**************218**************//
self.port = port
//**************218**************//
self.baudrate = baudrate
self.bytesize = bytesize
self.parity = parity
self.stopbits = stopbits
self.timeout = timeout
self.write_timeout = write_timeout
self.xonxoff = xonxoff
self.rtscts = rtscts
self.dsrdtr = dsrdtr
self.inter_byte_timeout = inter_byte_timeout
self.exclusive = exclusive
# watch for backward compatible kwargs
if 'writeTimeout' in kwargs:
self.write_timeout = kwargs.pop('writeTimeout')
if 'interCharTimeout' in kwargs:
self.inter_byte_timeout = kwargs.pop('interCharTimeout')
if kwargs:
raise ValueError('unexpected keyword arguments: {!r}'.format(kwargs))
if port is not None:
self.open()
# - - - - - - - - - - - - - - - - - - - - - - - -
# to be implemented by subclasses:
# def open(self):
# def close(self):
# - - - - - - - - - - - - - - - - - - - - - - - -
#property
def port(self):
"""\
Get the current port setting. The value that was passed on init or using
setPort() is passed back.
"""
return self._port
#port.setter
def port(self, port):
"""\
Change the port.
"""
//*************************line 263**********************//
if port is not None and not isinstance(port, basestring):
raise ValueError('"port" must be None or a string, not {}'.format(type(port)))
was_open = self.is_open
if was_open:
self.close()
self.portstr = port
self._port = port
self.name = self.portstr
if was_open:
self.open()
-------------followed is serialwin32.py(version 3.3), 31 is marked-----------------------------------------
#! python
#
# backend for Windows ("win32" incl. 32/64 bit support)
#
# (C) 2001-2015 Chris Liechti <cliechti#gmx.net>
#
# This file is part of pySerial. https://github.com/pyserial/pyserial
# SPDX-License-Identifier: BSD-3-Clause
#
# Initial patch to use ctypes by Giovanni Bajo <rasky#develer.com>
# pylint: disable=invalid-name,too-few-public-methods
import ctypes
import time
from serial import win32
import serial
from serial.serialutil import SerialBase, SerialException, to_bytes, portNotOpenError, writeTimeoutError
class Serial(SerialBase):
"""Serial port implementation for Win32 based on ctypes."""
BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
9600, 19200, 38400, 57600, 115200)
def __init__(self, *args, **kwargs):
self._port_handle = None
self._overlapped_read = None
self._overlapped_write = None
//**************31**************//
super(Serial, self).__init__(*args, **kwargs)
//**************31**************//
Questions:
Any ideas how to solve the error?
Anyone who has used the MPU9250 with STM32F407G discovery board? Any suggestion?
two related issues on Stackoverflow
issue one: visit pyserial serialwin32.py has attribute error
issue two: visit Invensense Motion Driver 6.12 STM32 demo python don't work
Looking online, I found this Github repo that appears to correspond to the code you are working with. It appears eMPL-client.py is incompatible with newer versions of pyserial. Specifically, the __main__ routine requires numeric port identifiers, but the pyserial 3.3 serial.Serial requires textual port identifiers. I do not have the setup to test this, but you can try the following.
Install a fresh copy of Python 2.7, which is what eMPL-client.py targets. This is unrelated to pyserial 2.7.
In the fresh copy, install pyserial 2.7 and the other dependencies. Per the source, pyserial 2.7 uses numbers for ports. Pyserial 3.3 uses names for ports, whence the "port must be a string" error.
That should get you past the initial error, which is similar to this answer to the question you linked. At that point, it's probably time to pull out your oscilloscope and make sure the board is generating signals. If so, check the speed/baud/parity. I see that the source runs at 115200bps; maybe try 57600 instead, if your hardware supports it.
An alternative
To use eMPL-client.py with pyserial 3.3, in eMPL-client.py, look for the lines:
if __name__ == "__main__":
if len(sys.argv) == 2:
comport = int(sys.argv[1]) - 1 #### This is the line that triggers the issue
else:
print "usage: " + sys.argv[0] + " port"
sys.exit(-1)
Change the ####-marked line to
comport = sys.argv[1]
(make sure to keep the indentation the same!)
Then, in cmd.exe, run
python eMPL-client.py COM7
with the string port name, e.g., COM7, instead of a port number, e.g., 7.