Bosch Indego (gen.1) goes Teensy

It's for PCB1.01 version ,but here the wiring and the connector of my TCG158.

For pfod.
If you see connected , it's that the BT link is OK
If HMI not start it's because there is no data flow on the serial link between ESP32 and Teensy
Check wiring between the 2 serial PIn of teensy TX1 RX1 and ESP32 TX2 RX2 it's cross link

Into mower.h the port and speed for ESP32 com is here:
Code:
#define Bluetooth Serial1  // Ardumower default OK for ESP32 or HC05
#define BLUETOOTH_BAUDRATE  19200  // baudrate used for communication with Bluetooth module
The connection of the L298N modules are by me the same as yours Bernard. And identical with the comment in drivers.cpp
// pinDir connected to IN1
// pinEnable connected to IN2
// pinPWM connected to ENA
But the motors wont drive.

If I take a look at the datasheet of L298N, these need on IN1 & IN2 pins a 5V logic level. But I think the Teensy has only 3.3V output.
Can this be the problem?
 
Certainly NO ,because I use them for test and it mow my lawn for at least 10 Hours on TC/G158 and we use this driver on Sender with ESP32 3.3V MCU

BUT.
The firmware is change since my test and i add the support of brushless driver on it, and it's possible i have include a bug in this part.
So you need to take a look at the setting.
You tell me that you are using the RL2000 one , but it's not L298N version.
So you need to change in mower.h
line 163 etc
Code:
#if defined (RL2000)  // here all setting for YARDFORCE
//*****************possible list of motor driver set to :****************
// 1 for brushless ZS-X11H v1 Driver
// 2 for DC L298N Driver
// 3 for DC BTS7960 Driver
#define LEFT_MOTOR_DRIVER 2  //never mix BL and DC on drive motor
#define RIGHT_MOTOR_DRIVER 2
#define MOW_MOTOR_DRIVER 2
to use driver 2
 
Thanks Bernard!
Yes, this part I have adopted:
#if defined (RL2000) // here all setting for YARDFORCE
//*****************possible list of motor driver set to :****************
// 1 for brushless ZS-X11H v1 Driver
// 2 for DC L298N Driver
// 3 for DC BTS7960 Driver
#define LEFT_MOTOR_DRIVER 2 //never mix BL and DC on drive motor
#define RIGHT_MOTOR_DRIVER 2
#define MOW_MOTOR_DRIVER 2
#define BUMPER_IS_SWITCH true // set to true if the bumper is a single ON/OFF switch
#define BUMPER_REAR_EXIST false // set to true to manage the rear bumper connected on CAN3 J20 connector
#define BUMPER_ARE_NORMALY_CLOSED false // set to true if the bumper contact is closed when nothing is hit
#define START_BUTTON_IS_NC false //if button is normaly closed
// mower can have a cover that stop the mowing cycle but power still on the PCB,mower only start after closing the cover
// start button is under cover , so after push the start button you have 10 seconde to close cover and mower start
// openning the cover stop mowing cycle
#define MOWER_HAVE_SECURITY_COVER false // mower can have a cover that stop the mowing cycle but power still on the PCB,mower only start after closing the cover
#define INA226_MOW2_PRESENT false
#define INA226_MOW3_PRESENT false
#define ODOMETRY_ONLY_RISING false
#endif

In the teensy serial consol menue the nr 1 = motor test dont work. I dont know why.
But finally, after many hours I have noticed, I can drive the motors from the pfodApp in the manual section.
Forward is ok, left und right is ok, but reverse dont work :(
I think, here can be anything changed in the code?:unsure:

ps: and yes the L298N works with 3,3V logic level ;)
 
Last edited:
Thanks Bernard!
Yes, this part I have adopted:


In the teensy serial consol menue the nr 1 = motor test dont work. I dont know why.
But finally, after many hours I have noticed, I can drive the motors from the pfodApp in the manual section.
Forward is ok, left und right is ok, but reverse dont work :(
I think, here can be anything changed in the code?:unsure:

ps: and yes the L298N works with 3,3V logic level ;)
Try to put the pinenable to low in the speed<0 part of the code into driver.cpp
Use this code :
Code:
// L298N motor driver
// IN2/C(10)/PinPWM   IN1/D(12)/PinDir
// H                  L     Forward
// L                  H     Reverse
// pinDir  connected to IN1
// pinEnable  connected to IN2
// pinPWM  connected to ENA

void setL298N(int pinDir, int pinPWM , int pinEnable, int speed) {
  if (speed < 0) {
    digitalWrite(pinDir, HIGH) ;
    digitalWrite(pinEnable, LOW) ;
    analogWrite(pinPWM, abs(speed));
  } else {
    digitalWrite(pinDir, LOW) ;
    digitalWrite(pinEnable, HIGH) ;
    analogWrite(pinPWM, abs(speed));
  }
}
 
Good morning!
That helped, but not 100% Now drives the motors backwards, but chopped. I try to make later a video from it.

Actually I noticed I get a lot of warnings in the Arduino IDE by compile, and I cant rember if I have it from the beginning or is it a new problem :rolleyes:


** here is not all the warnings*** some other similarly warnings are here as below **
| ^~~~~~~
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:77:79: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
77 | char* rfidToDoNames[] = {"NOTHING", "RTS", "FAST_START", "NEW_AREA", "SPEED", "AREA1", "AREA2", "AREA3"};
| ^~~~~~~
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:77:88: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
77 | char* rfidToDoNames[] = {"NOTHING", "RTS", "FAST_START", "NEW_AREA", "SPEED", "AREA1", "AREA2", "AREA3"};
| ^~~~~~~
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:77:97: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
77 | char* rfidToDoNames[] = {"NOTHING", "RTS", "FAST_START", "NEW_AREA", "SPEED", "AREA1", "AREA2", "AREA3"};
| ^~~~~~~
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp: In member function 'char* Robot::statusNameList(byte)':
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:277:33: warning: invalid conversion from 'const char*' to 'char*' [-fpermissive]
277 | return statusNames[statusIndex];
| ~~~~~~~~~~~~~~~~~~~~~~~^
| |
| const char*
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp: In member function 'virtual void Robot::loop()':
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:7138:59: warning: comparison of integer expressions of different signedness: 'long unsigned int' and 'int' [-Wsign-compare]
7138 | if ((areaToGo == areaInMowing) && (totalDistDrive >= whereToStart * 100)) {
| ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp: In member function 'void Robot::_ZN5Robot9writeOnSDE6String.part.0(String)':
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:5426:34: warning: '.txt' directive writing 4 bytes into a region of size between 0 and 5 [-Wformat-overflow=]
5426 | sprintf(historyFilenameChar, "%02u%02u%02u%02u%02u.txt", datetime.date.year - 2000, datetime.date.month, datetime.date.day, datetime.time.hour, datetime.time.minute);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:5426:12: note: 'sprintf' output between 15 and 27 bytes into a destination of size 15
5426 | sprintf(historyFilenameChar, "%02u%02u%02u%02u%02u.txt", datetime.date.year - 2000, datetime.date.month, datetime.date.day, datetime.time.hour, datetime.time.minute);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp: In member function 'void Robot::_ZN5Robot11writeOnSDlnE6String.part.0(String)':
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:5451:34: warning: '.txt' directive writing 4 bytes into a region of size between 0 and 5 [-Wformat-overflow=]
5451 | sprintf(historyFilenameChar, "%02u%02u%02u%02u%02u.txt", datetime.date.year - 2000, datetime.date.month, datetime.date.day, datetime.time.hour, datetime.time.minute);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:5451:12: note: 'sprintf' output between 15 and 27 bytes into a destination of size 15
5451 | sprintf(historyFilenameChar, "%02u%02u%02u%02u%02u.txt", datetime.date.year - 2000, datetime.date.month, datetime.date.day, datetime.time.hour, datetime.time.minute);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp: In member function 'virtual void Robot::loadSaveRobotStats(boolean)':
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:397:32: warning: '%02d' directive writing between 2 and 3 bytes into a region of size between 0 and 7 [-Wformat-overflow=]
397 | sprintf(historyFilenameChar, "%02d%02d%02d%02d%02d.txt", datetime.date.year - 2000, datetime.date.month, datetime.date.day, datetime.time.hour, datetime.time.minute);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:397:32: note: directive argument in the range [0, 255]
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:397:10: note: 'sprintf' output between 15 and 23 bytes into a destination of size 15
397 | sprintf(historyFilenameChar, "%02d%02d%02d%02d%02d.txt", datetime.date.year - 2000, datetime.date.month, datetime.date.day, datetime.time.hour, datetime.time.minute);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp: In member function 'virtual void Robot::setup()':
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:3029:34: warning: '%02d' directive writing between 2 and 3 bytes into a region of size between 0 and 7 [-Wformat-overflow=]
3029 | sprintf(historyFilenameChar, "%02d%02d%02d%02d%02d.txt", datetime.date.year - 2000, datetime.date.month, datetime.date.day, datetime.time.hour, datetime.time.minute);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:3029:34: note: directive argument in the range [0, 255]
D:\Teensy-main - GitHub Boilevin\teensymower\robot.cpp:3029:12: note: 'sprintf' output between 15 and 23 bytes into a destination of size 15
3029 | sprintf(historyFilenameChar, "%02d%02d%02d%02d%02d.txt", datetime.date.year - 2000, datetime.date.month, datetime.date.day, datetime.time.hour, datetime.time.minute);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Opening Teensy Loader...
Memory Usage on Teensy 4.1:
FLASH: code:276484, data:50732, headers:8652 free for files:7790596
RAM1: variables:57024, code:273352, padding:21560 free for local variables:172352
RAM2: variables:12416 free for malloc/new:511872
All the warnings dont fit in one post. Here a zipped txt with the complete warnings.
Are these relevant warnings?
Should I better back to arduino 1.8 ?
Or better to try another compiler?
 

Attachments

The warnings are normal, I think the Arduino IDE 2 is a bit stricter than the 1

Maybe you can test the function of the motors with a simple script?
Pins must of course be adapted:

Code:
/*
 * This Arduino Nano ESP32 code was developed by newbiely.com
 *
 * This Arduino Nano ESP32 code is made available for public use without any restriction
 *
 * For comprehensive instructions and wiring diagrams, please visit:
 * https://newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-dc-motor
 */

#define PIN_ENA  D5 // The Arduino Nano ESP32 pin connected to the EN1 pin L298N
#define PIN_IN1  D4 // The Arduino Nano ESP32 pin connected to the IN1 pin L298N
#define PIN_IN2  D3 // The Arduino Nano ESP32 pin connected to the IN2 pin L298N

// The setup function runs once on reset or power-up
void setup() {
  // initialize digital pins as outputs.
  pinMode(PIN_IN1, OUTPUT);
  pinMode(PIN_IN2, OUTPUT);
  pinMode(PIN_ENA, OUTPUT);
}

// The loop function repeats indefinitely
void loop() {
  digitalWrite(PIN_IN1, HIGH); // control the motor's direction in clockwise
  digitalWrite(PIN_IN2, LOW);  // control the motor's direction in clockwise

  for (int speed = 0; speed <= 255; speed++) {
    analogWrite(PIN_ENA, speed); // speed up
    delay(10);
  }

  delay(2000); // rotate at maximum speed 2 seconds in clockwise direction

  // change direction
  digitalWrite(PIN_IN1, LOW);   // control the motor's direction in anti-clockwise
  digitalWrite(PIN_IN2, HIGH);  // control the motor's direction in anti-clockwise

  delay(2000); // rotate at maximum speed for 2 seconds in anti-clockwise direction

  for (int speed = 255; speed >= 0; speed--) {
    analogWrite(PIN_ENA, speed); // speed down
    delay(10);
  }

  delay(2000); // stop motor 2 second
}
 
Bernard can you check this section of code in mower.ccp ?
from line 380:
//left motor setting********************************************
pinMode(pinMotorLeftEnable, OUTPUT);
digitalWrite(pinMotorLeftEnable, LOW);
pinMode(pinMotorLeftBrake, OUTPUT);
digitalWrite(pinMotorLeftBrake, LOW);
pinMode(pinMotorLeftPWM, OUTPUT);
pinMode(pinMotorLeftDir, OUTPUT);

analogWriteFrequency(pinMotorLeftPWM, 10000);//default value
analogWriteFrequency(pinMotorLeftDir, 10000);
if ((LEFT_MOTOR_DRIVER == 1) || (LEFT_MOTOR_DRIVER == 4)){
analogWriteFrequency(pinMotorLeftPWM, PWM_FREQUENCY_ZSX11HV1);
analogWriteFrequency(pinMotorLeftDir, PWM_FREQUENCY_ZSX11HV1);
}
if (LEFT_MOTOR_DRIVER == 2) {
analogWriteFrequency(pinMotorLeftPWM, PWM_FREQUENCY_L298N);
analogWriteFrequency(pinMotorLeftDir, PWM_FREQUENCY_L298N);
here the pinMotorLeftDir get a PWM signal. Should there not be a logical LOW or HIGH?

ps: in the attachment the video. forward, left & right is perfect, but on the end the rewerse is very strange 🤪
 

Attachments

Last edited:
Oh sorry about that :oops:
Absolut kein Problem! Ich hätte das in der Code auch sehen können, dass er gar nich runterfährt, sondern einfach bei voller speed umpolt 🤪
Die gute an den L298N dass sie sehr günstig sind. Und man lernt bei solchen Versuchen immer etwas ;)
 
Really sorry for the bad code.
Yes need a logic value for DIR pin.
The PWM setup pin is for BTS7960 driver (need PWM on 1 pin to go FWD and PWM on other one for Backward), certainly need to adjust also this part of the code to match the L298N driver.

BUT not sure it's the issue because i use digitalwrite command and not analog on pindir
Also i don't understand the video.
DID you connect the odometry ??
Why the wheel run so fast ,maybe you use the manual command in free wheel mode (not on load) and the PID can do some bad result.

Please start by this way:
From PFOD
Into setting motor :
Speed max in pwm : set to a very low value (60 for example) to avoid trouble
And from test ODO menu
1 turn Forward and Rev

Now for the code i attach here, it's a very old version for a 4WD test mower using L298N and teensyPCB V1.01 (DO NOT UPLOAD IT) but you can follow the code to see the difference with my last version and find the bug.
Here i am sure that this code work with DC motor and L298N without smoke.

20240630_151420.jpg20240630_151445.jpg20240630_153159.jpg
 

Attachments

Thanks Bernard again! Yes, the ODO is not calibrated jet. I think also I need to calibrate tho ODO first. But today was a lot of rain outside.:(
Parallel I'm currently to soldering up the sender pcb and finish the cable connections from the front in the machine.
A lot of works for today again. :cool:
 
the ODO is not calibrated jet
You need to connect it and put a small value in the odo setting 100 ticks/rev for example to be sure.

For sender and if you have not yet power it:
I can create a post for the assembly order and safe powering.
 
The setting the motors is very strange. I can assume the following:
- if speed max in PWM lower than 100, the mower wont drive forward. Coil whine is to hear, but I think the power is to low under 100PWM.
- I have appr. 1200-1300 ticks per revolution
- after setting max pwm to 185, if I go to test ODO and 1 rev forward, then drive forward only appr. 950 ticks, then the mower stop and i hear the coil whinig (I think it stuck on low PWM)
- backwards drive the mower always with full speed :oops:

I dont understand how to setting the PID values.

ps: the backwards always full speed can be caused from the code problem. I will compare the code in your zip file with the actually.
 
Last edited:
You need to connect the ide console when the test is running to see what's append
Normally PID value are OK if you have a PWM max at 185 for a standard mower speed near 0.4 m/s

First you need to solve the forward rev issue.
Capture d'écran 2024-06-30 203846.png
can you add the yellow jumper and remove the orange 5V and test again the code
Connect like that:
pinDir connected to IN1
pinEnable connected to IN2
pinPWM connected to ENA

Code:
// L298N motor driver
// IN2/C(10)/PinPWM   IN1/D(12)/PinDir
// H                  L     Forward
// L                  H     Reverse
// pinDir  connected to IN1
// pinEnable  connected to IN2
// pinPWM  connected to ENA

void setL298N(int pinDir, int pinPWM , int pinEnable, int speed) {
  if (speed < 0) {
    digitalWrite(pinDir, HIGH) ;
    digitalWrite(pinEnable, LOW) ;
    analogWrite(pinPWM, abs(speed));
  } else {
    digitalWrite(pinDir, LOW) ;
    digitalWrite(pinEnable, HIGH) ;
    analogWrite(pinPWM, abs(speed));
  }
}
 
If the code above doesn´t work:
I have always used it like that(output and input parallel, enable bridged).

analogWrite(pinPWM, ((byte)speed)); (only with pins connected like in my drawing)

and lower the pwm frequency( with due it was 3900, but lower is better, if you dont mind whining)
l298.jpg
 
Exactly, the abs(speed) does! By reverse was the pwm negative. Now with the abs() function, ist the reverse as the same as forward!
One problem solved. ;)

With the jellow jumper on and without 5V from mainboard (5v comes from the L7805 on the L298N board) no changes on the function of the L298N.

@gk2 the bridged mode of the two sides of th L298N was planned by me from the beginning, if one side has not enough power.
And the pwm frequency I readed allready about it everywhere in the net, the L298N works with lower frequency better.

I will try tomorrow the bridged variant and the lower PWM frequency.
Today was the day long enough.
 
Last edited:
I will try tomorrow the bridged variant and the lower PWM frequency.
I have used bridge variant on the mow motor of the tianchen TC/G158 : no real change and extreme EMF noise (so the perimeter reading fail) and also it really heat a lot
So i think that you lost your time with the L298N driver build for mini DC motor .
Take a look at the middle of this post ,they use L298N, but the size of the motor :ROFLMAO:

Simply order 3 BTS7960 ;)
 
Jep Bernard, you're right. I have ordered last week allready 3 pc of the BTS7960 😅 Hopfully I will get these today.
For the mower motor I think are the L298N anyway to weak. (tested to break with the hand takes about 3 - 4 Amps)
But I checked the torque the drive motors befor I began to build the mower, and the drive motors have only about 0,3 - 1,2A in my tests if I try to break/slow down these with the hand. And gives a lot of torque (I cant stop it with the hands, without rotate the whole mower case.) The transmission on it has a big ratio from i=76. So the torque was really big by low Ampers.
From this aspect I have tried to use for the drive motors the cheaper L298N. These module are also a bit smaller then the BTS.
But I think the L298N has also a big voltage drop on load, so the big motors get to low power drived with the pwm signal. I think this is the main problem.
 
So, I couldn't pass up a little experiment today. :cool:
I wanted to find out whether a reasonable drive is possible with the L298N in parallel mode.

If somebody want to give a try for the L298N drivers in an Indego conversation, with the parallel connected methode from above,
it works as following. The pins should be connected as following (this is the alternative parallel mode):

OUT1 with OUT4 shorted - Mot +/-
OUT2 with OUT3 shorted - Mot +/-
ENA - bridged to 5V
ENB - bridged to 5V

IN1 - IN4 shorted - connect to PWM
IN2 - IN3 shorted - connect to Dir
- Enable not connected

The code in drivers.cpp from line 166 should be adapted as following:
// L298N motor driver
// IN2/C(10)/PinPWM IN1/D(12)/PinDir
// H L Forward
// L H Reverse
// pinDir connected to IN1
// pinEnable connected to IN2
// pinPWM connected to ENA

void setL298N(int pinDir, int pinPWM , int pinEnable, int speed) {
if (speed < 0) {
digitalWrite(pinDir, HIGH) ;
digitalWrite(pinEnable, LOW) ;
analogWrite(pinPWM, 255-((byte)abs(speed)));
} else {
digitalWrite(pinDir, LOW) ;
digitalWrite(pinEnable, HIGH) ;
analogWrite(pinPWM, ((byte)abs(speed))));

With these modification the mower drives normally, I would say very good, without any driving issues.
BUT! ☝️The heatsink will be already after 10 min slow driving test by 16°C environment about 25-27°C warm. I think for longtime using in the hot summer will not be powerful enough and the IC will overheat.

ps: I have the PWM frequency not changed. It is leaved by 10000. Absolute no whinig to hear.

Here a small video in manual mode. More was not possible today, the weather is rainy. The calibration and settings are also not 100% finalised, but "Roberta" drives.
 

Attachments

Last edited:
Back
Top