I don’t have a Fendt either, but I know who I can test with. Now it’s time to integrate the code with ino AGOPEN?
That is what I’m looking at now.
In the autosteer ino , how to disengage ? can we read something on CAN to know we are manually steering ?
Perfect, I have a rough simple ino I used to test. Perfect on a Massey setup I can share if you want?
With the Fendt without thinking too much you’ll need to use the Kbus or ISO bus to engage steering from joystick, disengage can be done with only the valve bus.
I suppose the A1 input could be replaced with steer enable from AOG and does it actually matter if AOG doesn’t know steer on the tractor has been disabled?
Steer on and off being by the AOG manual on screen steer switch?
This is what a had for a quick test on more of a Massey Ferguson setup, will just have to change the CAN filters and how it reads / sends the Fendt message and re-gig my green LED part.
Cutting out on Fendt I think will come from the normal message, think the Fendt numbers drop to zero when stopped. You really want it to auto stop AGO steering (to reset steering commands) then just use button engage
To replace the engage button and do it from the Joystick, Will have to add a second K-Bus or ISO-Bus.
Massey_AC_Demo_Tractor_Simulator.ino (2.5 KB)
You will need to download the BN08x files Math shared on the BN08x and make a folder like this picture to use this code (don’t need a BN08x connected tho):
do you know how to access to the steering wheel sensor on Fendt ?
Two places I’ve found it:
- On the ISO-Bus as a standard AC / PGN 44032 like the Massey Ferguson (must turn on ISO-Bus on the tractor screen)
- Or if you make a navigation controller on the valve bus, it’s all there coming from the Fendt steering controller (as per project two)
You can steal my JCB Fastrac Charles !
( wish you were more local )
This is very interesting but
Somebody know if this works with a steer ready valtra tractor ?
If you have one I’m sure it will work, just have to try. Test parts are cheap.
Parts are cheap, that is the best part about this system.
But thank you for taking time to explain and document how this works.
Also giving a working example and video of the expected results.
The biggest frustration in learning to code C or learn anything for that matter, is snippets of ideas taken out of context of the original program. Example that do not work or compute are a huge frustration.
This clearly works and works well.
@CommonRail , could you point me in the direction of any resources that explain the CAN mask and filter concept a bit more. I’m not sure I understand it correctly at the moment. Maybe I’m over thinking it but can’t just grasp it fully.
I agree. There is so much ‘advice’ out there based on little more knowledge than the questioner has.
The mark of someone who understands a subject properly is they are able to explain it (however complex it is) to a lay person in an easy to understand manner.
Umm, think i was playing with examples when i clicked haha.
But if you grasp this stuff first the filters will make sense, and you will be able to use the data you get from the CAN too:
-
Numbers in Binary, Hexadecimal, and Decimal (we use all of them).
-Also use a online caculator and make numbers and see what happens when you translate numbers between all three each way. -
Data types or sizes (understand the size in the number of binary bits), then what the max value looks like when you translate to HEX, and DEC.
-Also when you read the BIN numbers and store as unsigned variable vs signed variable -
Bit Shifting (<<) (>>) - this was new to me but really made me understand how to join binary numbers together really easily. And what happens when the variable data size is full.
-
Binary AND (&) OR (|) - More later down the track when detecting switches on the CAN this may be helpful functions.
Maybe start here: https://www.arduino.cc/en/Tutorial/Foundations/BitMask
On the Arduino the Serial.print() and Serial.write() commands both get on my nerves badly. Arduino has this madding want to write everything so that we can interpret it in ascii the serial output. To read it it is handy, to get the other electronic device to understand it not so handy.
On my current project I had to learn the “union” structure to have it properly print the HEX string. Union combines two variables to the same memory space. so if you combined a Double floating point number to a byte[7] array in a union, you could finally Serial.write(byte[7],8) it would come out looking right as 0x00000000. but in my case also had to do an endian swap.
here are some helpful links for talking computer;
https://onlinehextools.com/add-hex-numbers
https://www.scadacore.com/tools/programming-calculators/online-hex-converter/
https://gregstoll.com/~gregstoll/floattohex/
https://www.scadacore.com/tools/programming-calculators/online-checksum-calculator/
Here’s a little function I use to print bytes out in hex:
static inline void print_hex(uint8_t *data, int len) {
char temp[10];
for (int b=0;b < len; b++) {
sprintf(temp, "%.2x",data[b]);
Serial.print(temp);
}
Serial.println("");
}
I didn’t like using Serial.print’s number printing with the HEX flag because it wouldn’t print a leading zero on single digit numbers.
Somewhere I have a version that also prints out the ascii characters if the number happens to be ascii.
Personally when it comes to the data and keeping it simple, stop using HEX.
It’s much easier to understand when you always have the data as DEC when dealing with variable numbers like wheel angles / curves etc. (0-255)
For switch’s or states/modes (On / Off) use BIN as there will always be 8 switch options each data[ ] from the CAN message. (If there’s not 8 there was a few 0’s on the left they don’t worry about). Bit shifting topic is good to understand that tho. (00000000 - 11111111)
The only part I use HEX for is the CAN-ID. (00 - FF)
For the beginners these are all the same:
(0 - 255) DEC
(00 - FF) HEX
(00000000 - 11111111) BIN
I strongly disagree. Mainly because when you’re first looking at the data, you can only convert it to decimal if you know the field width and endianness (all CAN bus data should be little endian if it’s following standards). For raw dumps, hex is the way to go. It’s not complicated. Once numbers are identified, I use a simple union to make it easy to read the fields.
Here’s a structure to easily pull out numbers of various widths from the CAN bus messages. Cast your byte buffer to (BytesUnion *) and then you can easily read out any particular field without worrying about manually parsing bytes in the right order (assuming again it’s little Endian which it should be).
typedef union {
uint64_t uint64;
uint32_t uint32[2];
uint16_t uint16[4];
uint8_t uint8[8];
int64_t int64;
int32_t int32[2];
int16_t int16[4];
int8_t int8[8];
uint8_t bytes[8];
uint8_t byte[8]; //alternate name so you can omit the s if you feel it makes more sense
} BytesUnion;
For example, if your data buffer is candata, you could do something like:
(BytesUnion *)candata->uint32[0] //first 32-bit unsigned value
(BytesUnion *)candata->uint16[0] //first 16-bit unsigned value
etc.