jaded
Solar Newcomer
Posts: 3
|
Post by jaded on May 19, 2019 18:25:40 GMT
Hello, I am trying to connect my Renogy Rover 20 Amp to a Raspberry pi using either the included data cable (USB) or a cable I built for GPIO. The code being used is the Python code from www.rototron.info/raspberry-pi-solar-serial-rest-api-tutorial/ and I am getting a "bytearray index out of range" error when the pin signal is low and different message when its high. The GPIO pins are tested to be working by using a RS232 to USB adapter and wiring it up to the raspberry pi then monitoring the port on the pi while I send data from my PC. Tested with /dev/ttyUSB0 and /dev/ttyAMA0. Same results with both. Can anyone help? Here is the code I am using:from flask import Flask, jsonify
from time import sleep
from serial import Serial
import sys
sys.path.append('/home/pi/tracer/python')
from tracer import Tracer, TracerSerial, QueryCommand
port = Serial('/dev/ttyAMA0', 9600, timeout=1)
port.flushInput()
port.flushOutput()
tracer = Tracer(0x16)
t_ser = TracerSerial(tracer, port)
query = QueryCommand()
try:
while 1:
try:
t_ser.send_command(query)
data = t_ser.receive_result()
except (IndexError , IOError) as e:
print(e)
port.flushInput()
port.flushOutput()
sleep(4)
continue
print('Battery Voltage: {0:0.1f}V'.format(data.batt_voltage))
print('Solar Panel Voltage: {0:0.1f}V'.format(data.pv_voltage))
print('Charging Current: {0:0.2f}A'.format(data.charge_current))
print('Load Current: {0:02.f}A\n'.format(data.load_amps))
sleep(4)
except KeyboardInterrupt:
print ("\nCrtl-C pressed. Closing serial port and exiting...")
finally:
port.close() Results:pi@rpi-solar:~/Documents $ python solar_test.py
bytearray index out of range
bytearray index out of range
^C
Crtl-C pressed. Closing serial port and exiting...
|
|
jaded
Solar Newcomer
Posts: 3
|
Post by jaded on May 19, 2019 21:56:59 GMT
OK so I confirmed that the hardware is working by using the mbpoll utility and setting it to 9600 8N1. From the data returned in [10]: 6164 and cross referenced with the Rover Modbus document I can see that it is working correctly. Decimal 6164 is Hex 1814 and when the bytes are split they correspond to my Rover which is 24v and 20amp. So the last part is getting the Python script to work... pi@rpi-solar:~/Documents $ mbpoll -b 9600 -P none -m rtu -a 1 -r 10 -c 40 /dev/ttyUSB0 mbpoll 1.4-12 - FieldTalk(tm) Modbus(R) Master Simulator Copyright © 2015-2019 Pascal JEAN, github.com/epsilonrt/mbpollThis program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; type 'mbpoll -w' for details. Protocol configuration: Modbus RTU Slave configuration...: address = [1] start reference = 10, count = 40 Communication.........: /dev/ttyUSB0, 9600-8N1 t/o 1.00 s, poll rate 1000 ms Data type.............: 16-bit register, output (holding) register table -- Polling slave 1... Ctrl-C to stop) [10]: 6164 [11]: 5120 [12]: 21070 [13]: 18221 [14]: 17236 [15]: 21068 [16]: 11602 [17]: 22098 [18]: 20551 [19]: 12848 [20]: 1 [21]: 773 [22]: 0 [23]: 1280 [24]: 4615 [25]: 100 [26]: 1 [27]: 2 [28]: 1 [29]: 26 [30]: 1924 [31]: 8 [32]: 1 [33]: 3 [34]: 0 [35]: 60 [36]: 0 [37]: 8 [38]: 0 [39]: 786 [40]: 48815 (-16721) [41]: 101 [42]: 32770 (-32766) [43]: 0 [44]: 0 [45]: 10162 [46]: 0 [47]: 0 [48]: 0 [49]: 0
|
|
jaded
Solar Newcomer
Posts: 3
|
Post by jaded on May 22, 2019 4:26:19 GMT
Alright. I got everything working. Turns out the original code I was using was not correct. I ended up using code from github.com/corbinbs/solarshed instead. The actual python script is called renogy_rover.py and I modified it to output in InfluxDB line format to be consumed by Telegraf and sent to InfluxDB where it is displayed using Grafana. Grafana DashboardSample output:pi@rpi-solar:/usr/local/bin $ solar solar_shed solar_volts=0.0,amp_charge_today=1,amp_discharge_today=0,battery_percent=61,battery_volts=12.4,solar_amps=0.0,load_volts=12.4,load_amps=0.0,load_watts=0,solar_watts=0,watts_gen_today=12,temp_controller=59.0,temp_battery=57.2 Here is the code I am using: #!/usr/bin/python """ Driver for the Renogy Rover Solar Controller using the Modbus RTU protocol """
import minimalmodbus
minimalmodbus.BAUDRATE = 9600 minimalmodbus.TIMEOUT = 0.5
BATTERY_TYPE = { 1: 'open', 2: 'sealed', 3: 'gel', 4: 'lithium', 5: 'self-customized' }
CHARGING_STATE = { 0: 'deactivated', 1: 'activated', 2: 'mppt', 3: 'equalizing', 4: 'boost', 5: 'floating', 6: 'current limiting' }
class RenogyRover(minimalmodbus.Instrument): """ Communicates using the Modbus RTU protocol (via provided USB<->RS232 cable) """
def __init__(self, portname, slaveaddress): minimalmodbus.Instrument.__init__(self, portname, slaveaddress)
def model(self): """ Read the controller's model information """ return self.read_string(12, numberOfRegisters=8)
def system_voltage_current(self): """ Read the controler's system voltage and current Returns a tuple of (voltage, current) """ register = self.read_register(10) amps = register & 0x00ff voltage = register >> 8 return (voltage, amps)
def version(self): """ Read the controler's software and hardware version information Returns a tuple of (software version, hardware version) """ registers = self.read_registers(20, 4) soft_major = registers[0] & 0x00ff soft_minor = registers[1] >> 8 soft_patch = registers[1] & 0x00ff hard_major = registers[2] & 0x00ff hard_minor = registers[3] >> 8 hard_patch = registers[3] & 0x00ff software_version = 'V{}.{}.{}'.format(soft_major, soft_minor, soft_patch) hardware_version = 'V{}.{}.{}'.format(hard_major, hard_minor, hard_patch) return (software_version, hardware_version)
def serial_number(self): """ Read the controller's serial number """ registers = self.read_registers(24, 2) return '{}{}'.format(registers[0], registers[1])
def battery_percentage(self): """ Read the battery percentage """ return self.read_register(256) & 0x00ff
def battery_voltage(self): """ Read the battery voltage """ return self.read_register(257, numberOfDecimals=1)
def battery_temperature(self): """ Read the battery surface temperature """ register = self.read_register(259) battery_temp_bits = register & 0x00ff temp_value = battery_temp_bits & 0x0ff sign = battery_temp_bits >> 7 battery_temp = -(temp_value - 128) if sign == 1 else temp_value return battery_temp
def controller_temperature(self): """ Read the controller temperature """ register = self.read_register(259) controller_temp_bits = register >> 8 temp_value = controller_temp_bits & 0x0ff sign = controller_temp_bits >> 7 controller_temp = -(temp_value - 128) if sign == 1 else temp_value return controller_temp
def load_voltage(self): """ Read load (raspberrypi) voltage """ return self.read_register(260, numberOfDecimals=1)
def load_current(self): """ Read load (raspberrypi) current """ return self.read_register(261, numberOfDecimals=2)
def load_power(self): """ Read load (raspberrypi) power """ return self.read_register(262)
def solar_voltage(self): """ Read solar voltage """ return self.read_register(263, numberOfDecimals=1)
def solar_current(self): """ Read solar current """ return self.read_register(264, numberOfDecimals=2)
def solar_power(self): """ Read solar power """ return self.read_register(265)
def charging_amp_hours_today(self): """ Read charging amp hours for the current day """ return self.read_register(273)
def discharging_amp_hours_today(self): """ Read discharging amp hours for the current day """ return self.read_register(274)
def power_generation_today(self): return self.read_register(275)
def charging_status(self): return self.read_register(288) & 0x00ff
def charging_status_label(self): return CHARGING_STATE.get(self.charging_status())
def battery_capacity(self): return self.read_register(57346)
def voltage_setting(self): register = self.read_register(57347) setting = register >> 8 recognized_voltage = register & 0x00ff return (setting, recognized_voltage)
def battery_type(self): register = self.read_register(57348) return BATTERY_TYPE.get(register)
#TODO: resume at 3.10 of spec
if __name__ == "__main__": rover = RenogyRover('/dev/ttyUSB0', 1) # print('Model: ', rover.model()) # print('Battery %: ', rover.battery_percentage()) # print('Battery Type: ', rover.battery_type()) # print('Battery Capacity: ', rover.battery_capacity()) # print('Battery Voltage: ', rover.battery_voltage()) battery_temp = rover.battery_temperature() # print('Battery Temperature: ', battery_temp, battery_temp * 1.8 + 32) controller_temp = rover.controller_temperature() # print('Controller Temperature: ', controller_temp, controller_temp * 1.8 + 32) # print('Load Voltage: ', rover.load_voltage()) # print('Load Current: ', rover.load_current()) # print('Load Power: ', rover.load_power()) # print('Charging Status: ', rover.charging_status_label()) # print 'solar ' 'voltage='+str(rover.solar_voltage()) # print('Solar Current: ', rover.solar_current()) # print('Solar Power: ', rover.solar_power()) # print('Power Generated Today (kilowatt hours): ', rover.power_generation_today()) # print('Charging Amp/Hours Today: ', rover.charging_amp_hours_today()) # print('Discharging Amp/Hours Today: ', rover.discharging_amp_hours_today()) print "solar_shed " "solar_volts="+str(rover.solar_voltage())+",amp_charge_today="+str(rover.charging_amp_hours_today())+",amp_discharge_today="+str(rover.discharging_amp_hours_today())+",battery_percent="+str(rover.battery_percentage())+",battery_volts="+str(rover.battery_voltage())+",solar_amps="+str(rover.solar_current())+",load_volts="+str(rover.load_voltage())+",load_amps="+str(rover.load_current())+",load_watts="+str(rover.load_power())+",solar_watts="+str(rover.solar_power())+",watts_gen_today="+str(rover.power_generation_today())+",temp_controller="+str(controller_temp * 1.8 +32)+",temp_battery="+str(battery_temp * 1.8 +32)
|
|
|
Post by playersz28 on May 24, 2019 12:33:56 GMT
Does that code do anything with the data?
I'm running a Pi/Rover setup and feeding a SQL db and displaying charts. I still need to convert the INA219 library from Python to C++ though so that I don't need the ESP8266 just for the 219. Mine is based off the EPSolarServer code.
|
|