from __future__ import print_function import os import sys import glob import datetime from shutil import copyfile try: import RPi.GPIO as GPIO except: pass import subprocess import numpy as np import threading import multiprocessing as mp from time import sleep, time from IPython import embed from uldaq import (get_daq_device_inventory, DaqDevice, AInScanFlag, ScanStatus, ScanOption, create_float_buffer, InterfaceType, AiInputMode) def GPIO_setup(LED1_pin, LED2_pin, LED_out_pin, Button1_pin, Button2_pin, power_controll_pin): # LED output pins GPIO.setmode(GPIO.BOARD) GPIO.setup(LED1_pin, GPIO.OUT) # 1 GPIO.output(LED1_pin, GPIO.LOW) GPIO.setup(LED2_pin, GPIO.OUT) # 2 GPIO.output(LED2_pin, GPIO.HIGH) if LED_out_pin != None: GPIO.setup(LED_out_pin, GPIO.OUT) GPIO.output(LED_out_pin, GPIO.LOW) LED_status = [False, True, False] else: LED_status = [False, True] # switch controlled input # GPIO.setup(Button1_pin, GPIO.IN) GPIO.setup(power_controll_pin, GPIO.IN) GPIO.setup(Button1_pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) GPIO.setup(Button2_pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) return LED_status def read_cfg(cfg_file, now, start_time=None, init_read=False): cfg_f = open(cfg_file, 'r+') cfg = cfg_f.readlines() ### read cfg information ### if init_read: for line in cfg: if "PathFormat" in line: path_format = ':'.join(line.split(':')[1:]).strip().replace('"', '').replace("'", "") cfg_f.close() return path_format else: for line in cfg: if 'Columns1' in line: n_cols = int(line.split(':')[1].strip()) elif 'Rows1' in line: n_rows = int(line.split(':')[1].strip()) elif 'Extra1' in line: n_extra = int(line.split(':')[1].strip()) elif "AISampleRate" in line: samplerate = int(float(line.split(':')[-1].strip().replace('kHz', '')) * 1000) elif "AIMaxVolt" in line: max_v = float(line.split(':')[1].strip().replace('mV', '')) elif 'Gain' in line: gain = int(line.split(':')[1].strip()) channels = n_rows * n_cols + n_extra ### alter information and re-write ### for enu, line in enumerate(cfg): if "StartDate" in line: cfg[enu] = (' StartDate : %s\n' % now.strftime('%Y-%m-%d')) elif "StartTime" in line: if start_time == None: cfg[enu] = (' StartTime : %s\n' % (now.strftime('%H:%M:%S') + now.strftime(".%f")[:4])) else: cfg[enu] = (' StartTime : %s\n' % ('%2.f:%2.f:00' % (start_time[0], start_time[1]))) cfg_f.close() cfg_f = open(cfg_file, 'w+') for line in cfg: cfg_f.write(line) cfg_f.close() return channels, samplerate, n_cols, n_rows, max_v, gain def clock_process(end_clock, run_led_pin, sync_led_pin, w1_bus_path, temp_f, led_f): t0 = time() run_led_interval = 2 sync_led_interval = 1 temp_interval = 300 next_t_t = 0 next_l_t = 0 print("\nDatetime: %.0f:%0f o'clock" % (datetime.datetime.now().hour, datetime.datetime.now().minute)) print("Terminate: %.0f:%0f o'clock" % (end_clock[0], end_clock[1])) while True: if datetime.datetime.now().hour >= end_clock[0] and datetime.datetime.now().minute >= end_clock[1]: print('\nEnd time reached ...') break if (time() - t0) % temp_interval <= 0.1: #GPIO.output(run_led_pin, GPIO.HIGH) GPIO.output(sync_led_pin, GPIO.HIGH) sleep(0.1) #GPIO.output(run_led_pin, GPIO.LOW) GPIO.output(sync_led_pin, GPIO.LOW) w1_f = open(w1_bus_path, 'r') w1_file = w1_f.readlines() for line in w1_file: if 't=' in line: temp = float((line.split('=')[-1].strip())) / 1000 temp_f.write('%6.0f; %7.3f\n' % (next_t_t, temp)) temp_f.flush() break w1_f.close() next_t_t += temp_interval elif (time() - t0) % run_led_interval <= 0.1: #GPIO.output(run_led_pin, GPIO.HIGH) GPIO.output(sync_led_pin, GPIO.HIGH) sleep(0.1) #GPIO.output(run_led_pin, GPIO.LOW) GPIO.output(sync_led_pin, GPIO.LOW) elif (time() - t0) % sync_led_interval <= 0.1: GPIO.output(sync_led_pin, GPIO.HIGH) sleep(0.1) GPIO.output(sync_led_pin, GPIO.LOW) if led_f != None: led_f.write('%.4f' % (next_l_t)) led_f.flush() next_l_t += sync_led_interval else: pass def save_process(q, f, gain): while True: if q.empty(): pass elif q.full(): print('\n!!! Queue full !!!') else: Cdata = q.get() # print(Cdata[:10]) Cdata.tofile(f) f.flush() def save_controll(q, pin): while True: if q.empty(): sleep(0.1) pass else: trigger = q.get() GPIO.output(pin, GPIO.HIGH) sleep(0.5) GPIO.output(pin, GPIO.LOW) def main(): LED1_pin = 11 LED2_pin = 13 LED_out_pin = 35 Button1_pin = 16 Button2_pin = 18 power_controll_pin = 37 LED_status = GPIO_setup(LED1_pin, LED2_pin, LED_out_pin, Button1_pin, Button2_pin, power_controll_pin) # switch LEDs off GPIO.output(LED1_pin, GPIO.LOW) LED_status[0] = False GPIO.output(LED2_pin, GPIO.LOW) LED_status[1] = False last_button_2_t = time() now = datetime.datetime.now() # defined start and end time valid = False if len(sys.argv) == 3: if len(sys.argv[1]) == 4 and len(sys.argv[2]) == 4: start_clock = [int(sys.argv[1][:2]), int(sys.argv[1][2:])] end_clock = [int(sys.argv[2][:2]), int(sys.argv[2][2:])] valid = True if not valid: start_clock = [10, 0] end_clock = [16, 0] # get init cfg if os.path.exists('/media/pi/data1'): init_path = '/media/pi/data1' elif os.path.exists('/home/raab/data/rasp_test'): init_path = '/home/raab/data/rasp_test' else: for i in range(10): GPIO.output(LED1_pin, GPIO.HIGH) sleep(0.5) GPIO.output(LED1_pin, GPIO.LOW) sleep(0.5) print('got no path') quit() init_cfgfile = os.path.join(init_path, 'fishgrid.cfg') if os.path.exists(init_cfgfile): path_format = read_cfg(init_cfgfile, now, init_read = True) else: print('cfg file missing !!!') quit() # create save folder and copy cfg file start_str = ('%2.f_%2.f' % (start_clock[0], start_clock[1])).replace(' ', '0') path = os.path.join(init_path, now.strftime(path_format[:-9]) + start_str) #ToDo: Edit here if not os.path.exists(path): os.makedirs(path) copyfile(os.path.join(os.path.split(path)[0], 'fishgrid.cfg'), os.path.join(path, 'fishgrid.cfg')) cfgfile = os.path.join(path, 'fishgrid.cfg') # read and edit config file channels, rate, n_cols, n_rows, max_v, gain = read_cfg(cfgfile, now, start_clock) file = os.path.join(path, 'traces-grid1.raw') temp_file = os.path.join(path, 'temperatures.csv') led_file = os.path.join(path, 'led_times.csv') led_file2 = os.path.join(path, 'led_idxs.csv') # find w1bus for temp record_temp = False temp_f = None w1_bus_path = glob.glob('/sys/bus/w1/devices/28*/w1_slave') if len(w1_bus_path) > 0: w1_bus_path = w1_bus_path[0] record_temp = True temp_f = open(temp_file, 'w') temp_f.write('%-6s; %-7s\n' % ('time/s', 'T/C')) f = open(file, 'wb') led_f = open(led_file, 'w') led_f2 = open(led_file2, 'w') # f.close() # DAQ setup if True: status = ScanStatus.IDLE descriptor_index = 0 range_index = 0 interface_type = InterfaceType.USB low_channel = 0 high_channel = channels - 1 buffer_sec = 20 samples_per_channel = rate * buffer_sec # * channels = Buffer size buffer_size = samples_per_channel * channels print('\nChannels: %.0f' % channels) # rate = 20000 scan_options = ScanOption.CONTINUOUS flags = AInScanFlag.DEFAULT # Get descriptors for all of the available DAQ devices. devices = get_daq_device_inventory(interface_type) number_of_devices = len(devices) if number_of_devices == 0: raise Exception('Error: No DAQ devices found') print('Found', number_of_devices, 'DAQ device(s):') for i in range(number_of_devices): print(' ', devices[i].product_name, ' (', devices[i].unique_id, ')', sep='') # Create the DAQ device object associated with the specified descriptor index. daq_device = None daq_device = DaqDevice(devices[descriptor_index]) # Get the AiDevice object and verify that it is valid. ai_device = None ai_device = daq_device.get_ai_device() if ai_device is None: raise Exception('Error: The DAQ device does not support analog input') # Verify that the specified device supports hardware pacing for analog input. ai_info = ai_device.get_info() if not ai_info.has_pacer(): raise Exception('\nError: The specified DAQ device does not support hardware paced analog input') # Establish a connection to the DAQ device. descriptor = daq_device.get_descriptor() print('\nConnecting to', descriptor.dev_string, '- please wait...') daq_device.connect() # The default input mode is SINGLE_ENDED. input_mode = AiInputMode.SINGLE_ENDED # If SINGLE_ENDED input mode is not supported, set to DIFFERENTIAL. if ai_info.get_num_chans_by_mode(AiInputMode.SINGLE_ENDED) <= 0: input_mode = AiInputMode.DIFFERENTIAL # Get the number of channels and validate the high channel number. number_of_channels = ai_info.get_num_chans_by_mode(input_mode) if high_channel >= number_of_channels: high_channel = number_of_channels - 1 channel_count = high_channel - low_channel + 1 # Get a list of supported ranges and validate the range index. ranges = ai_info.get_ranges(input_mode) int_ranges = [] for r in ranges: int_ranges.append(int(r.name.replace('BIP', '').replace('VOLTS', ''))) for idx in np.argsort(int_ranges): if max_v * gain / 1000 <= int_ranges[idx]: range_index = idx break print(ranges[range_index]) GPIO.output(LED1_pin, GPIO.HIGH) LED_status[0] = True GPIO.output(LED2_pin, GPIO.LOW) LED_status[1] = False sleep(.5) GPIO.output(LED1_pin, GPIO.LOW) LED_status[0] = False GPIO.output(LED2_pin, GPIO.HIGH) LED_status[1] = True sleep(.5) GPIO.output(LED1_pin, GPIO.HIGH) LED_status[0] = True GPIO.output(LED2_pin, GPIO.LOW) LED_status[1] = False sleep(.5) GPIO.output(LED1_pin, GPIO.LOW) LED_status[0] = False GPIO.output(LED2_pin, GPIO.HIGH) LED_status[1] = True sleep(.5) GPIO.output(LED2_pin, GPIO.LOW) LED_status[1] = False ########################## ToDo: continue here !!! disp_eth_power = True stop_flag = False while True: if datetime.datetime.now().hour == start_clock[0] and datetime.datetime.now().minute == start_clock[1]: break elif datetime.datetime.now().hour * 60 + datetime.datetime.now().minute >= start_clock[0] * 60 + start_clock[1]: # elif datetime.datetime.now().hour >= start_clock[0] and datetime.datetime.now().minute >= start_clock[1]: h = datetime.datetime.now().hour m = datetime.datetime.now().minute start_clock = [h, m] # end_clock = [h + 6, m] GPIO.output(LED2_pin, GPIO.HIGH) LED_status[1] = True #clock_thread = threading.Thread(target=clock_controll, args=(end_clock, LED1_pin, LED_out_pin, w1_bus_path, temp_f, led_f, lambda: stop_flag)) #clock_thread.start() # clock_thread = mp.Process(target=clock_process, args=(end_clock, LED1_pin, LED_out_pin, w1_bus_path, temp_f, led_f)) # clock_thread.start() # # q = mp.Queue() # # save_thread = mp.Process(target=save_process, args=(q, f, gain)) # # save_thread.start() # save_thread = mp.Process(target=save_controll, args=(q, LED1_pin)) # save_thread.start() print('\nRecording started.') data = create_float_buffer(channel_count, samples_per_channel) print('----') print('Buffer size: %.0fn; %.0fsec' % (len(data), buffer_sec)) print('Channels: %.0f' % channel_count) print('Samples per channel: %.0f' % samples_per_channel) print('----') LED_t0 = time() LED_t_interval = 5 sync_LED_t_interval = 1 temp_t0 = time() next_temp_t = 0 temp_interval = 300 # sec --> 5 min next_l_t = 0 disp_eth_power = True rate = ai_device.a_in_scan(low_channel, high_channel, input_mode, ranges[range_index], samples_per_channel, rate, scan_options, flags, data) status, transfer_status = ai_device.get_scan_status() last_idx = 0 # while GPIO.input(Button1_pin) == GPIO.LOW and clock_thread.is_alive(): #while GPIO.input(Button1_pin) == GPIO.LOW and datetime.datetime.now().hour * 60 + datetime.datetime.now().minute < end_clock[0] * 60 + end_clock[1]: buffer_no = 0 while GPIO.input(Button1_pin) == GPIO.LOW: if GPIO.input(Button2_pin) == GPIO.HIGH: if (time() - last_button_2_t) > 5: if disp_eth_power == True: subprocess.run(['tvservice', '-o']) subprocess.run(['vcgencmd', 'display_power', '0'])# subprocess.run(['sudo', 'ip', 'link', 'set', 'eth0', 'down']) GPIO.output(LED2_pin, GPIO.LOW) disp_eth_power = False last_button_2_t = time() elif disp_eth_power == False: subprocess.run(['tvservice', '-p']) subprocess.run(['vcgencmd', 'display_power', '1']) subprocess.run(['sudo', '/bin/chvt', '6']) subprocess.run(['sudo', '/bin/chvt', '7'])# subprocess.run(['sudo', 'ip', 'link', 'set', 'eth0', 'up']) GPIO.output(LED2_pin, GPIO.HIGH) disp_eth_power = True last_button_2_t = time() ################# if record_temp == True: if time() - temp_t0 > next_temp_t: w1_f = open(w1_bus_path, 'r') w1_file = w1_f.readlines() for line in w1_file: if 't=' in line: temp = float((line.split('=')[-1].strip())) / 1000 temp_f.write('%6.0f; %7.3f\n' % (next_temp_t, temp)) temp_f.flush() break w1_f.close() next_temp_t += temp_interval # blinking LED (run) if (time() - LED_t0) % LED_t_interval < .5 and LED_status[0] == False: # if (time() - LED_t0) % LED_t_interval < .5: LED_status[0] = True GPIO.output(LED1_pin, GPIO.HIGH) elif (time() - LED_t0) % LED_t_interval >= .5 and LED_status[0] == True: # elif (time() - LED_t0) % LED_t_interval >= .5: LED_status[0] = False GPIO.output(LED1_pin, GPIO.LOW) else: pass if (time() - LED_t0) % sync_LED_t_interval < .1 and LED_status[2] == False: if led_f != None: Cidx = int((buffer_size * buffer_no + last_idx) / channels) led_f.write('%.4f\n' % (time()-LED_t0)) led_f.flush() led_f2.write('%.0f\n' % Cidx) led_f2.flush() LED_status[2] = True GPIO.output(LED_out_pin, GPIO.HIGH) elif (time() - LED_t0) % sync_LED_t_interval >= .1 and LED_status[2] == True: LED_status[2] = False GPIO.output(LED_out_pin, GPIO.LOW) else: pass # if time() - LED_t < .1 and LED_status[0] == False: # LED_status[0] = True # GPIO.output(LED1_pin, GPIO.HIGH) # if time() - LED_t >= .1 and LED_status[0] == True: # LED_status[0] = False # GPIO.output(LED1_pin, GPIO.LOW) # if time() - LED_t >= LED_t_interval: # LED_t = time() ########################################## # Get the status of the background operation status, transfer_status = ai_device.get_scan_status() index = transfer_status.current_index # print(index) ### the new way ### # if index == -1: # continue # # if index > save_range[0] and index <= save_range[1]: # pass # # else: # GPIO.output(LED1_pin, GPIO.HIGH) # dt = time() - cont_t # cont_t = time() # # Cdata = np.copy(np.array(data[save_range[0]:save_range[1]], dtype=np.float32) / gain) # q.put(Cdata) # # save_ranges = np.roll(save_ranges, -1, axis=0) # save_range = save_ranges[0] # # # GPIO.output(LED1_pin, GPIO.LOW) ###---### ### the old way ### if index < 0 or index == last_idx: continue if index > last_idx: (np.array(data[last_idx:index], dtype=np.float32) / gain).tofile(f) else: (np.array(data[last_idx:], dtype=np.float32) / gain).tofile(f) if datetime.datetime.now().hour * 60 + datetime.datetime.now().minute >= end_clock[0] * 60 + end_clock[1]: f.flush() GPIO.output(LED1_pin, GPIO.LOW) GPIO.output(LED_out_pin, GPIO.LOW) break (np.array(data[:index], dtype=np.float32) / gain).tofile(f) f.flush() buffer_no += 1 last_idx = index ###---### #stop_flag = True #clock_thread.join() # print('\nEmpty Queue') # while not q.empty(): # sleep(0.01) # clock_thread.terminate() # save_thread.terminate() # save_thread.terminate() print('\nDone!') f.close() temp_f.close() led_f.close() GPIO.output(LED1_pin, GPIO.HIGH) GPIO.output(LED2_pin, GPIO.HIGH) sleep(2) GPIO.output(LED1_pin, GPIO.LOW) GPIO.output(LED2_pin, GPIO.LOW) if daq_device: # Stop the acquisition if it is still running. if status == ScanStatus.RUNNING: ai_device.scan_stop() if daq_device.is_connected(): daq_device.disconnect() daq_device.release() if disp_eth_power == False: subprocess.run(['tvservice', '-p']) subprocess.run(['vcgencmd', 'display_power', '1']) subprocess.run(['sudo', '/bin/chvt', '6']) subprocess.run(['sudo', '/bin/chvt', '7']) # subprocess.run(['sudo', 'ip', 'link', 'set', 'eth0', 'up']) GPIO.cleanup() if __name__ == '__main__': main()