Arctic Hare mod by Jussi

Perfect
If you use the Pi code, normaly you Don't have to change anything into Azurit When rain is detected the button_home_click() send the mower to station.

I am not sure it's usefull to add the rainWS var but the rainUse need to be set to true and Don't forget to add this var in RpiRemote.cpp.

Also a new Var "stayInStationDuration" need to be set with a duration depending of the WeatherStation result or the timer start again the mower :blink:


The main loop is the def CheckSerial()
To start the readWS() each 10 seconde:


Code:
if  (time.time() > mower.timeToReadWS)):
    mower.timeToReadWS=time.time() +10
     readWS()



I work a lot on the code this week end so please remember where you have add data if you want to update.

For the Gyro it's better to find a GY88 but you can also use 2 parts ,a GY521 and a HMC5883 locate inside a GPS M8N https://www.amazon.fr/ZkeeShop-MPU6050-HMC5883L-Compatible-Arduino/dp/B072M7SY13
I have this 2 parts working together into Paranello mower:
GY521 connected on IMU I2c port, Compass on I2C5,GPS on GPS port (Maybe Workarround on PCB1.3) https://www.marotronics.de/3-Achsen-Gy-521-Gyroskop-Accelerometer-MPU-6050-Raspberry-Pi-Arduino https://www.marotronics.de/Beitian-BN-880-Flight-Control-Dual-GPS-Modul
 
PiArdu rainWS var is unnecessary.. I have rain sensor on pcb lid also. I was thinking that it's better use same "method" for both
Doesn't sending 'go home' every ten seconds cause erros or something strange? (if raining)
Where to put 'stayInStationDuration', maybe I can use rain in timer.h --> stateCurr == STATE_STATION && rain == 0

Yes, updating would be nightmare :D

This works but how to change it "greater than 0" when trying that I get only errors

Code:
if str(wsrain)!="0.00":


This works better, if weather station server is down mower won't think that it's raining

Code:
def readWS():
    wsrain = subprocess.Popen("curl [URL]http://192.168.1.11/meteograph.cgi?text=last60m_rain0_total_mm",[/URL] stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True)
    output, error_output = wsrain.communicate()
    #print(float(output))
    #print(error_output)
    if float(output)>0:
        print("Rain detected on weather station")
        consoleInsertText("Rain detected on weather station" + 'n')
        #button_home_click() # Go home
        #send_pfo_message('rh','1','2','3','4','5','6',) # Go home
        send_var_message('w','rainWS','1','0','0','0','0','0','0','0')
    else:
        print("No rain on last 60 minutes")
        consoleInsertText("No rain on last 60 minutes" + 'n')
        send_var_message('w','rainWS','0','0','0','0','0','0','0','0')
 
Finaly i thing i Don't understand what you want to do because i have thought that you Don't have rainsensor on the mower and use the WS instead.
I have never tested the rainsensor on PCB1.3 and not sure it work on my version ????

To "stayInStationDuration" Simply change the next time to check timer
Actualy the timer is check each 1 minute.
it's "nextTimeTimer" into timer.h line 20

So simply into Python :
tempvar=myMower.millis+3600000 #it's 1hours?
send_var_message('w','nextTimeTimer',tempvar,'0','0','0','0','0','0','0')
and create the var in RpiRemote.cpp

By this way the mower stay in the station for 1 hour.

if str(wsrain)!="0.00":

Have you tested

Code:
if int(wsrain)>=0 :
 
Rainsensor works fine. I want to add weather station rain sensor because I have it and mower is under the roof.

Code:
TypeError: Can't convert 'int' object to str implicitly
Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.5/tkinter/__init__.py", line 1562, in __call__
    return self.func(*args)
  File "/usr/lib/python3.5/tkinter/__init__.py", line 608, in callit
    func(*args)
  File "/home/pi/Documents/PiArdumower/PiArdu.py", line 481, in checkSerial
    readWS()
  File "/home/pi/Documents/PiArdumower/PiArdu.py", line 436, in readWS
    tempvar=mymower.millis+120000
TypeError: Can't convert 'int' object to str implicitly
 
it's difficult to answer without the code but
try to convert to int
tempvar=int(mymower.millis)+120000
and when send the message use str()
send_var_message('w','nextTimeTimer',''+str(int(tempvar))+'','0','0','0','0','0','0','0')
it's 2 ' and not " before +str(
You can check the mower.status and mower.state to know where is the mower.

Also
You need to check if the subprocess is not blocking fonction until receive the answer ?? WS of for example ?
 
Thanks, seems to be working now. It checks both rain sensors once every minute


Code:
def readWS():
    tempvar=int(mymower.millis)+120000
    wsrain = subprocess.Popen("curl [URL]http://192.168.1.11/meteograph.cgi?text=last60m_rain0_total_mm",[/URL] stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True)
    output, error_output = wsrain.communicate()
    #print(output)
    #print(error_output)
    if str(output)!="b''":
        if float(output)>0:
            print("Rain detected on weather station")
            consoleInsertText("Rain detected on weather station" + 'n')
            send_var_message('w','rainWS','1','0','0','0','0','0','0','0')
            send_var_message('w','stayInStationDuration',''+str(int(tempvar))+'','0','0','0','0','0','0','0')
        else:
            print("No rain on last 60 minutes")
            consoleInsertText("No rain on last 60 minutes" + 'n')
            send_var_message('w','rainWS','0','0','0','0','0','0','0','0')
            send_var_message('w','stayInStationDuration','mymower.millis','0','0','0','0','0','0','0')
    else:
        print("ERROR! Connection problem..")
        consoleInsertText("ERROR! Connection problem.." + 'n')


timer.h

Code:
// check timer
void Robot::checkTimer() {

  if ((millis() < nextTimeTimer) || (millis() < stayInStationDuration)) return;
  nextTimeTimer = millis() + 60000;  // one minute check
  srand(time2minutes(datetime.time)); // initializes the pseudo-random number generator for c++ rand()
.....


robot.cpp

Code:
if ((rainUse) && (millis() >= nextTimeRain)) {
    // read rain sensor
    nextTimeRain = millis() + 60000; // changed 5000 -> 60000
    rain = ((readSensor(SEN_RAIN) != 0) || (rainWS != 0));
    if (rain) rainCounter++;


RpiRemote.cpp

Code:
if (strncmp(variable_name[i], "rainWS", 20) == 0)  robot->rainWS = atoi(received_value[i]);
if (strncmp(variable_name[i], "stayInStationDuration", 20) == 0)  robot->stayInStationDuration = atoi(received_value[i]);
 
Hi.
Good i see that you understand the code but it's not exactly what i have thought.;)
Why manage the stayInStationDuration into Azurit.
Simply change the value of "nextTimeTimer"

Code:
tempvar=int(myMower.millis)+3600000 #it's 1hours?
send_var_message('w','nextTimeTimer',tempvar,'rainWS','1','0','0','0','0','0')


Also in one shot you can send 4 variables value into send_var_message (it's var1,value1,var2,value2,var3 etc.……)

What the brand and model of your Rain station ?
 
I was wondering why theres so many zeros :D

You are right stayInStationDuration is not needed, mixed up it with nextTimeRain
And no need to set nextTimeTimer to mymower.millis when not raining

Another option is this:

Code:
// start timer triggered
            stopTimerTriggered = false;
            if ((stateCurr == STATE_STATION) && (rain == 0)) {
              Console.print("Timer ");
              Console.print(i);
              Console.println(F(" timer start triggered"));


Weather station is Davis vantage pro 2

btw. Do you run piardu as service?
 
btw. Do you run piardu as service?
I use a tactile screen on the mower (to start,stop etc...) and the soft start on Raspbian startup using the file mower.sh so PyArdu is Always running on the mower and record all the console data for debug.
When i want to take control i use VNC like in this video for example: https://www.ardumower.de/index.php/...ion/1841-multiple-perimeter-area-mowing#17296
The mower is used at hotspot because i Don't have WIFI in the garden https://www.youtube.com/watch?v=XgcDipALFOc&t=37s But after many days sometimes the Pi bug and for the moment i don't understand why ?:evil:
 
Have you looked /var/log/syslog and /var/log/kern.log
I'll try running it as service, we'll see what happens
 
Have you find a GY88 on the net ?
Thanks For the log i try to check on next bug, but today all work perfectly.
 
Running PiArdu as service on raspbian

Code:
sudo systemctl --force --full edit piardu.service

my piardu.service looks this

Code:
[Unit]
Description=ArdumowerCC
After=multi-user.target

[Service]
User=pi
WorkingDirectory=/home/pi/Documents/PiArdumower
ExecStart=/bin/bash /home/pi/bin/piardumower.sh
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/pi/.Xauthority"
Restart=on-abort

[Install]
WantedBy=graphical.target

piardumower.sh (I'm not sure is this needed because working path etc. are defined on service. So it may be possible to run python3 piardu.py without bash script..)

Code:
#!/bin/bash
cd /home/pi/Documents/PiArdumower/
/usr/bin/python3 PiArdu.py

enable, start and check. reboot and check again

Code:
sudo systemctl enable piardu.service
sudo systemctl start piardu.service
sudo systemctl status piardu.service
 
I'm trying to add second mower motor also to piardu.py. motor1MowSenseScale and ..2.. is added succesfully but with motor1MowSense and ...2.. something missing
Error what I get:

Code:
During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.5/tkinter/__init__.py", line 1562, in __call__
    return self.func(*args)
  File "/usr/lib/python3.5/tkinter/__init__.py", line 608, in callit
    func(*args)
  File "/home/pi/Documents/PiArdumower/PiArdu.py", line 506, in checkSerial
    decode_message(message)
  File "/home/pi/Documents/PiArdumower/PiArdu.py", line 696, in decode_message
    mymower.motor1MowSense=message.motor1MowSense
  File "/home/pi/Documents/PiArdumower/pynmea2/nmea.py", line 155, in __getattr__
    raise AttributeError(name)
AttributeError: motor1MowSense
Exception in Tkinter callback
Traceback (most recent call last):
  File "/home/pi/Documents/PiArdumower/pynmea2/nmea.py", line 153, in __getattr__
    i = t.name_to_idx[name]
KeyError: 'motor1MowSense'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.5/tkinter/__init__.py", line 1562, in __call__
    return self.func(*args)
  File "/usr/lib/python3.5/tkinter/__init__.py", line 608, in callit
    func(*args)
  File "/home/pi/Documents/PiArdumower/PiArdu.py", line 506, in checkSerial
    decode_message(message)
  File "/home/pi/Documents/PiArdumower/PiArdu.py", line 696, in decode_message
    mymower.motor1MowSense=message.motor1MowSense
  File "/home/pi/Documents/PiArdumower/pynmea2/nmea.py", line 155, in __getattr__
    raise AttributeError(name)
AttributeError: motor1MowSense

Any idea what I'm missing? Its plot what causes this
 
Hi Jussip.
It's not the plot.
The Due rpiremote send the message with Nmea protocol.
The Pi Decode it using PyNmea module So:

When you want to add a message or change the contain of a sentence you need to do the change also in Pynmea.
You can find this into PiArdumower/pynmea2/types
Open the talker.py
.
Here you can find all the message description(message.motorMowSense etc.…..), in your case it's the RMMOW message so forget the RM and search MOW it's the sentence name: you find that:

Code:
class MOW(TalkerSentence):
    """ non stop message from DUE to PI  for mow motor plot and visu etc....
    """
    fields = (
        ("Millis", "millis"),
        ("motorMowSense", "motorMowSense"),
        ("motorMowPWMCurr", "motorMowPWMCurr"),
        ("BatVoltage", "batVoltage"),

Adapt it according the Due rpiremote.

Something like that:

Code:
class MOW(TalkerSentence):
    """ non stop message from DUE to PI  for mow motor plot and visu etc....
    """
    fields = (
        ("Millis", "millis"),
        ("motor1MowSense", "motor1MowSense"),
        ("motor2MowSense", "motor2MowSense"),
        ("motorMowPWMCurr", "motorMowPWMCurr"),
        ("BatVoltage", "batVoltage"),

So now if you send correctly the message with rpiRemote you can have acces to message.motor2MowSense.

For the Plot it's a simple texte file so add your data and use KST to rebuild the plotMow.kst using the wizard (see video on KST on the net)

Code:
f=open(cwd + "/log/PlotMow.txt",'a+')
                f.write("{};{};{}n".format((int(mymower.millis)-firstplotMowx)/1000,float(mymower.motorMowSense) , float(mymower.motorMowPWMCurr)))
                f.close()

I have make a lot of change in the code (For the mow motor to stop slowly and restart automaticly after overcurrent) so if you change something put a tag before like i do "//bber13 14 etc..." to avoid nighmare:evil: or send me the change so i can add them into the original code.
 
Here the last version.

BE CARREFUL that i have change the eeprom mapping ,so you need a factory setting and rewrite all your setting using PFOD.

To see change you can search for //bber12 , 13 14 on the whole code.
The last Pi code is the PiArdu96.py

Correct bug in mow motor management and into rolltoinside state, add the keyboad remote in manual mode etc.......

PIAZURITBER.zip

Attachment: https://forum.ardumower.de/data/media/kunena/attachments/3545/PIAZURITBER.zip/
 
Zuletzt bearbeitet von einem Moderator:
I can do changes so that theres new setting, e.g. secondMowMotor = True. What is best way to send you changes? Collecting them to text file or something else..
 
Oben