Impulse's per 100m!

Have AOG send this PGN:
PGN

It is the one I use for the rate controller. It has 2 bytes for speed.

Here are the changes for AOG:

  1. UDPComm.Designer.cs line 883 (end of class)

     #region PGN35400 to Rate Controller
     void SendPGN35400()
     {
         try
         {
             WatchDogCounts++;
             if (WatchDogCounts * tmrWatchdog.Interval > 750)    // 750 ms timer
             {
                 WatchDogCounts = 0;
                 if (isUDPSendConnected)
                 {
                     int Temp;
                     byte[] Data = new byte[10];
                     Data[0] = 138;
                     Data[1] = 72;
                     IPAddress RCip;
                     IPEndPoint RCendPt;
    
                     // worked area
                     Temp = (int)(fd.workedAreaTotal / 100.0);   // square meters / 100 = hectares * 100
                     Data[2] = (byte)(Temp >> 8);
                     Data[3] = (byte)Temp;
    
                     // working width
                     // is supersection on?
                     Temp = 0;
                     if (section[tool.numOfSections].isSectionOn)
                     {
                         Temp = (int)(tool.toolWidth * 100.0);
                     }
                     else
                     {
                         // individual sections are possibly on
                         for (int i = 0; i < tool.numOfSections; i++)
                         {
                             if (section[i].isSectionOn) Temp += (int)(section[i].sectionWidth * 100.0);
                         }
                     }
                     Data[4] = (byte)(Temp >> 8);
                     Data[5] = (byte)Temp;
    
                     // speed
                     Temp = (int)(pn.speed * 100);
                     Data[6] = (byte)(Temp >> 8);
                     Data[7] = (byte)Temp;
    
                     // relay bytes
                     BuildMachineByte();
                     Data[8] = mc.machineData[mc.mdSectionControlByteHi];
                     Data[9] = mc.machineData[mc.mdSectionControlByteLo];
    
                     // send data
                     RCip = IPAddress.Parse("127.100.0.0");
                     RCendPt = new IPEndPoint(RCip, 8120);
                     sendSocket.BeginSendTo(Data, 0, Data.Length, SocketFlags.None, RCendPt, new AsyncCallback(SendData), null);
                 }
    
             }
         }
         catch (Exception ex)
         {
    
         }
     }
     #endregion
    
  2. GUI.Designer.cs line 1266 (at the start of the tmrWatchdog_tick sub)
    // send PGN to rate controller
    SendPGN35400();

  3. FormGPS.cs line 251
    // RateController timer
    private int WatchDogCounts = 0;

1 Like

@SK21, @BrianTee_Admin is their a reason this can’t go in a live version of AOG? Does it mess anything else up?

I guess it would have to be modified to sent the PGN out the machine port as well as the local host, which it does now.

That’s a loaded question. I don’t think Brian wants to support/troubleshoot all the questions if he adds everyone’s custom pgn, nevermind the potential for bugs & errors. That being said I have a custom pgn too that I’d like added to the main AoG branch so that I don’t have to add it manually each time he releases a new version. Is it possible to fork my own copy of AoG, modify it but still grab his updates later?

Your right Brian has enough to do without supporting all the minor changes to AOG that people want to make. I would also like to know how Github might help with this.

Here is a modified version of the changes that will send the PGN out on the machine port with UDP and out on USB. This is just for anyone interested in doing on their own.

  1. UDPComm.Designer.cs line 883 (end of class)

     #region PGN35400 to Rate Controller
     void SendPGN35400()
     {
         try
         {
             WatchDogCounts++;
             if (WatchDogCounts * tmrWatchdog.Interval > 750)    // 750 ms timer
             {
                 WatchDogCounts = 0;
                 int Temp;
                 byte[] Data = new byte[10];
                 Data[0] = 138;
                 Data[1] = 72;
    
                 // worked area
                 Temp = (int)(fd.workedAreaTotal / 100.0);   // square meters / 100 = hectares * 100
                 Data[2] = (byte)(Temp >> 8);
                 Data[3] = (byte)Temp;
    
                 // working width
                 // is supersection on?
                 Temp = 0;
                 if (section[tool.numOfSections].isSectionOn)
                 {
                     Temp = (int)(tool.toolWidth * 100.0);
                 }
                 else
                 {
                     // individual sections are possibly on
                     for (int i = 0; i < tool.numOfSections; i++)
                     {
                         if (section[i].isSectionOn) Temp += (int)(section[i].sectionWidth * 100.0);
                     }
                 }
                 Data[4] = (byte)(Temp >> 8);
                 Data[5] = (byte)Temp;
    
                 // speed
                 Temp = (int)(pn.speed * 100);
                 Data[6] = (byte)(Temp >> 8);
                 Data[7] = (byte)Temp;
    
                 // relay bytes
                 BuildMachineByte();
                 Data[8] = mc.machineData[mc.mdSectionControlByteHi];
                 Data[9] = mc.machineData[mc.mdSectionControlByteLo];
    
                 if (isUDPSendConnected)
                 {
                     // send data
                     // local host
                     IPAddress RCip = IPAddress.Parse("127.100.0.0");
                     IPEndPoint RCendPt = new IPEndPoint(RCip, 8120);
                     sendSocket.BeginSendTo(Data, 0, Data.Length, SocketFlags.None, RCendPt, new AsyncCallback(SendData), null);
    
                     // Lan
                     IPEndPoint epAutoSteer = new IPEndPoint(epIP, Properties.Settings.Default.setIP_autoSteerPort);
                     sendSocket.BeginSendTo(Data, 0, Data.Length, SocketFlags.None, epAutoSteer, new AsyncCallback(SendData), null);
                 }
    
                 if (spMachine.IsOpen)
                 {
                     // send data USB
                     try
                     {
                         spMachine.Write(Data, 0, Data.Length);
                     }
                     catch (Exception e)
                     {
                         WriteErrorLog("PGN35400 to Machine Port " + e.ToString());
                     }
                 }
    
             }
         }
         catch (Exception ex)
         {
    
         }
     }
     #endregion
    
  2. GUI.Designer.cs line 1266 (at the start of the tmrWatchdog_tick sub)
    // send PGN to rate controller
    SendPGN35400();

  3. FormGPS.cs line 251
    // RateController timer
    private int WatchDogCounts = 0;

1 Like

v4.3 - the release version is almost ready. Haven’t updated the older v4.2 in a bit for sure - but there kind of is no point.

I have a local server in AOG already, we never did finalize how AOG to app would be be best for all applications anyone would want to write.

Seeding and harvest is starting here - time for me will be very short :frowning:

Don’t you also need each section width to be sent as well to determine rate for that one section or more when on?

Does AOG only need to send out PGN35400? Not receive anything? Does your app also have its own connection (usb,udp) to external rate control hardware, also, does it need to modify the data normally sent out AOG’s machine port for section control?

The rate controller only needs to receive PGN35400. The pgn includes a value for working width to account for turning sections off and on. The app has its own serial connection and UDP connection. It doesn’t use the machine port. It connects over local host to AOG. It uses the existing PGN32761 in AOG for controlling the sections.

Any chance you can change the pgn # to be close to the existing ones? You are in the negative region of a signed 16 bit integer. Nice to keep them all in one place. There is an excel sheet on v4 branch, and there are already 4 rate pgns for rate, not sure the status of them, or if Matthias still uses them.

Regarding working width, that is the total of the sections, but how are your setting rate for the width of each section when they are independently on or off?

Screenshot_2

1 Like

Yes, I found out about the negative signed 16 bit integer the hard way! I can change the pgn. It was just a random number. I was trying to keep out of everybody’s way with the pgns.

The working width varies with which sections are on. I only have rate control for the entire machine, not left and right separately.

I’ll look at that excel sheet and pick a number close that no one is using if the existing ones won’t work.

I’m not sure if j1939 compatibility is something you’re shooting for, but J1939 PGNs are unsigned 16 bit integers, so they can be up to 65535. A lot of proprietary messages I’ve seen are 65535. Also J1939 values are little endian. Although it doesn’t really matter. The current messages aren’t formatted for J1939 anyway.

Doesn’t matter to me. I know if you use a signed integer with 35400 on a Nano33 it works, but on a Nano it doesn’t. A Nano33 uses 4 bytes for an integer. Took a while to figure that out :slight_smile: Probably better to keep it simple and limit it to 32767 or lower.

Here is the new PGN:

  1. UDPComm.Designer.cs line 883 (end of class)

     #region PGN32740 to Rate Controller
     void SendPGN32740()
     {
         try
         {
             WatchDogCounts++;
             if (WatchDogCounts * tmrWatchdog.Interval > 750)    // 750 ms timer
             {
                 WatchDogCounts = 0;
                 int Temp;
                 byte[] Data = new byte[10];
                 Data[0] = 127;
                 Data[1] = 228;
    
                 // worked area
                 Temp = (int)(fd.workedAreaTotal / 100.0);   // square meters / 100 = hectares * 100
                 Data[2] = (byte)(Temp >> 8);
                 Data[3] = (byte)Temp;
    
                 // working width
                 // is supersection on?
                 Temp = 0;
                 if (section[tool.numOfSections].isSectionOn)
                 {
                     Temp = (int)(tool.toolWidth * 100.0);
                 }
                 else
                 {
                     // individual sections are possibly on
                     for (int i = 0; i < tool.numOfSections; i++)
                     {
                         if (section[i].isSectionOn) Temp += (int)(section[i].sectionWidth * 100.0);
                     }
                 }
                 Data[4] = (byte)(Temp >> 8);
                 Data[5] = (byte)Temp;
    
                 // speed
                 Temp = (int)(pn.speed * 100);
                 Data[6] = (byte)(Temp >> 8);
                 Data[7] = (byte)Temp;
    
                 // relay bytes
                 BuildMachineByte();
                 Data[8] = mc.machineData[mc.mdSectionControlByteHi];
                 Data[9] = mc.machineData[mc.mdSectionControlByteLo];
    
                 if (isUDPSendConnected)
                 {
                     // send data
                     // local host
                     IPAddress RCip = IPAddress.Parse("127.100.0.0");
                     IPEndPoint RCendPt = new IPEndPoint(RCip, 8120);
                     sendSocket.BeginSendTo(Data, 0, Data.Length, SocketFlags.None, RCendPt, new AsyncCallback(SendData), null);
    
                     // Lan
                     IPEndPoint epAutoSteer = new IPEndPoint(epIP, Properties.Settings.Default.setIP_autoSteerPort);
                     sendSocket.BeginSendTo(Data, 0, Data.Length, SocketFlags.None, epAutoSteer, new AsyncCallback(SendData), null);
                 }
    
                 if (spMachine.IsOpen)
                 {
                     // send data USB
                     try
                     {
                         spMachine.Write(Data, 0, Data.Length);
                     }
                     catch (Exception e)
                     {
                         WriteErrorLog("PGN32740 to Machine Port " + e.ToString());
                     }
                 }
             }
         }
         catch (Exception ex)
         {
    
         }
     }
     #endregion
    
  2. GUI.Designer.cs line 1266 (at the start of the tmrWatchdog_tick sub)
    // send PGN to rate controller
    SendPGN32740();

  3. FormGPS.cs line 251
    // RateController timer
    private int WatchDogCounts = 0;

1 Like

That great @SK21, look forward to 0.1 speed accuracy in master version!
Would a pull request be better on github, then if Brian’s happy he could just merge?
See Master, Forks, Pull request’s & Commits

Not sure about pull request, never did it.

So really all you need is the stuff you want in the PGN sent locally 127.0.0.1 ?

I’m thinking a bit how to make this more universal - not just Rate App specific code. I already have interApp checkbox in udp, so if that is checked then can set up a fully asynchronous udp local server and then send and receive any PGN we want for any future application.

That application then is responsible to set up its own udp or usb ports for communication to modules.

Sound acceptable?

Yes that sounds ok. How would that work in the case of Brofarm? He would need an app on the tablet that would send the pgn to his connected esp. If the pgn was sent to the serial port or udp then all he would have to do is connect to the comm port without the need for an app.

Getting really busy farming - but here is the pgn’s that were originally set aside for rate control.

So further expanding the basic app concept, can make 7FF0 thru F2 as return to AOG, and the basic data as you request could be 7FF3. I’ll try to get that udp local server finished up, and controlled via that interapp setting on the udp form.

Are you in a hurry to get this to work? Seeding/harvest is making my AOG time quite limited.

Screenshot_2

1 Like

Please concentrate on your seeding, that’s more important.

1 Like

No hurry here. I’ll make rate controller match your pgns when you are finished.

Came across this tonight https://mediatum.ub.tum.de/thumb2/732576

Din 9684-1 7 pin tractor plug standard.
Actually shows 6v on impulse’s, but it seems to work on 5v.