Help needed in designing system

@Sindel

This is my take on the setup, with what I have and what I know.

  1. Motor ($19)

Brushless-Efficiency-Drones-Gimbal

  1. Sensor and magnet ($16):

https://www.digikey.com/en/products/detail/ams/AS5047P-TS-EK-AB/5452344

  1. Board (about $10)

  1. ESP32 Wroom ($10)

HiLetgo-ESP-WROOM-32-Development-Microcontroller-Integrated

image

  1. Off-shelf commercial WiFi router (assume you got it)

  2. Off-shelf notebook (assume you got it)

Each setup is approximately $60, before tax, shipping, 3D printing, extra cables, power supply, etc.

I have 5 alpha-version mosquito boards, you can power them up with the Wroom, because I messed up the LDO and one of the pins, but they are working.

This is how they look

Hey @Valentine thanks for the parts list and the diagram!
The Alpha Mosquito boards are the ones without the angle sensor, right?
How much would you charge for shipping to the Netherlands?
Ideally Iā€™d like to try just one, to see if the whole system works, before scaling to 5.
Ah, I usually use the ESP32-Pico instead of the WROOM, but I guess it shouldnā€™t be a problem.

@sindel

PM/DM me on the board.

Cheers,
Valentine

Hi there!

Cool project!

Maybe Iā€™m missing something but to keep things as simple as possible you could use a spiral spring
for the spool that keeps on rewinding the thread. Maybe you know that feature from that old vacuum cleaners that spool the cable in automatically. You could also add a wireless button for a break if you need to.

Hey, @Lukas, I had the same thought, but I assume @Sindel has a reason for using the motorsā€¦

if not, then a simple tape measure from the hardware store is a possible source for such a spring in a compact package - you could probably just replace the tape with a spindle and some stringā€¦

Hey there!
Vert legitimate question! And itā€™s the same idea I had at the beginning of the project.
And I obviously tried it by using a tape measure, but I warped the spring very quickly.
Also I need something that can provide at least 30 meters of thread. Tape measures are usually around 10 meters of extension.
I donā€™t know if Iā€™m missing any easier method, but after this failure I thought to go the electronic way and got myself some DC motors. And now hopefully Iā€™ll transition to BLDC.
I love the creative thinking on this forum! Thanks for your input!

Your other problem would be, basics physics, that as you wind the spring, the force coefficient will gradually increase and the force to unwind will increase, and at the end you will chop your head off especially when you have to unwind that long distance. You could avoid this by designing a clock-like mechanism where the force is constant (similar to the way clockworks are designed) however mechanically this is way too complex. Also you still need the angle sensor electronics to communicate the angle wirelessly.

Using a brushless motor is perhaps the lesser of two evils.

1 Like

The way you usualy get constant tension is with some sort of, wellā€¦ tension measuring device, either you use tensometers or you use a dance roll (pun not intended).
Dance roll is simpler to implement.
How it works is this - you have a potentiometer that changes its value with the angle of the dance roll arm, at the end of the arm you can have a small weight (usualy you would use a proportional pneumatic cylinder to keep calibrated counter force on the arm).
Your thread will go around a pulley at the end of this arm.
What you do now is this - you set up a PID controler that tries to keep the angle of the arm constant (to keep the voltage read from the potentiometer constant). This PID controls speed of the motor.
Done - the control loop will now keep constant tension on the string.

BTW what is the purpose of the string in this performance? :smiley:

EDIT1: Added a drawing:

EDIT2: I forgot to tell - with this method you donā€™t need a BLDC, the DC motors should be sufficient, you just need a H-bridge like the venerable L298M. This is because the feedback from the dancer is sufficient to control the whole thing.

EDIT3: Or just ditch the position and speed loops in SimpleFOC and put some constant value into Q voltage PID, put 0 into D current PID input (you dont need field weakening for this), this desired value of Q current will control motor current, this is directly proportional to torque - you control the winding torque, you control the tension. This way there is no need for any measurement device.

Thing is if the line has slack or breaks the motor will want to wind very fast (in all of these methods).

Well, you can do it in plain software as well, no need fo external hardware (if you have current sensing). Below is a piece of my code for demonstration, which does exactly what you are looking for. Take it as pseudo code, I deleted a lot of my specific code and removed the setup and motor/sensor definitions. Also, you probably wonā€™t need any communication with a central controller, if the strings for all actors should just be pulled with constant force, which would eliminate all the Wi-Fi equipment and communication code. The concept is to use SimpleFOC in Angle mode and to limit the motor torque by setting a current limit (without further a do, it would then act like a spring). In the loop function you sense the current, if it exceeds your set limit, the dancer pulls the string and you set the angle to the position to where the dancer pulled it. If the current is lower then set, the rope is looser and you correct the angle a few degrees in the opposite direction, which pulls it again. Works perfectly fine in my application. You will need to adjust some parameters of course, especially the correction of a loose rope and how frequent you call that code needs to be adjusted to be really smooth, but that is easy. If you miss something essential in the code excerpt, just let me know.

Have fun with it,

  • Chris
//*************************************************************************
//*************************************************************************
/*
		WARNING: This code is incomplete, just showing the concept of
		pulling a string with constant force.
		
		Most of the SimpoleFOC standard code and setup is left out.
	
*/
//*************************************************************************
//*************************************************************************


#define RADIUS    		0.01				// Radius of spool in m
#define TORQUE2FORCE(T)	((T)*1.0F/RADIUS)	// Convert Nm to N 	
#define FORCE2TORQUE(F)	((F)*RADIUS)		// Convert Nm to N 	

// Motor dependent constants
#define IMAX			5.7F	// Max phase current in A
#define TORQUE_PER_A	0.035F	// Torque in Nm per Ampere

// Utility functions
float GetCurrent()
{
	const DQCurrent_s c = GetCurrents();
	const float Current = (fabs(c.d) + fabs(c.q));
	return Current;
}

float GetForce()
{
	float Current = GetCurrent();
	float Torque = Current * TORQUE_PER_A;
	float Force = TORQUE2FORCE(Torque);
	// Serial.printf("Force: %4.1fN\n", Force);
	return Force;
}

// Set the target shaft angle to Angle in rad and move there at speed Speed in rad/s
void ReceivedSetAngle(float Angle, float Speed)
{
	motor.velocity_limit = Speed;
	motor.P_angle.limit  = Speed;
	motor.move(ROT_DIR*Angle);
}

void ReceivedSetAngleMode()
{
	motor.controller = MotionControlType::angle;  
	motor.foc_modulation = FOCModulationType::SinePWM;
}

void ReceivedSetForce(float Force)
{
	const float Torque = FORCE2TORQUE(Force);
	float Current = Torque / TORQUE_PER_A;
	Current = min(Current, IMAX);
	Serial.printf("New force: %.2fN=%.3fA\n", Force, Current);
	motor.current_limit = Current;
	if(_isset(motor.phase_resistance) || motor.torque_controller != TorqueControlType::voltage ) 
		motor.PID_velocity.limit = Current;
}

void setup() 
{
	...
}

void loop() 
{
	uint32_t TNow=millis(); 
	static uint32_t TSPushPull=TNow;
	static float CurrentLP = GetCurrent();

	#ifdef USE_HALLSENSOR
		sensor.update();
	#endif

	#ifndef USE_COMMANDER
		SerialLoop();
	#endif
	motor.loopFOC();

	// LPF currents		
	CurrentLP = 0.7*CurrentLP + 0.3*GetCurrent();

	if (...initialization)
	{
		// Add a homing procedure etc. here!
		// E.g. pull the string until the current rises signifiucantly, then set this as the zero position.
		
		// Once the homing is done:
		ReceivedSetAngleMode();	
		motor.loopFOC();
		motor.move();
		ReceivedSetForce(NEUTRAL_FORCE);
		ReceivedSetAngle(NewAngle, 5.0F);
		TSPushPull = TNow + 100;
	}

	//************************************************************
	// Mimic the bahavior of pulling on the control lines
	if (... initialized && TSPushPull<=TNow)
	{
		float Force = GetForce();
		if (Force>NEUTRAL_FORCE+3)
		{
			// Break pulled
			ReceivedSetAngle(motor.shaftAngle(), 100.0F);
			// Serial.println("Pulled");
		}
		else if (Force<NEUTRAL_FORCE-1)
		{
			// Break loose
			ReceivedSetAngle(motor.shaftAngle()+12, 100.0F);
			// Serial.println("Pushed");
		}
		TSPushPull += 50;
	}


	//************************************************************
	// Motion control function
	{
		// velocity, position or voltage (defined in motor.controller)
		// this function can be run at much lower frequency than loopFOC() function
		// You can also use motor.move() and set the motor.target in the code
		//***  NB: 1rad = 57.3 Grad, 6.283rad=360 Grad, 1000rpm=6283rad/m=103.9rad/s

		#ifdef USE_COMMANDER
			motor.move();
		#else
			// Serial.printf("Setting target to %.1f\n", TargetValue);
			motor.move(TargetValue);
			// motor.move(0);
		#endif

		// function intended to be used with serial plotter to monitor motor variables
		// significantly slowing the execution down!!!!
		motor.monitor();
	}
}

Hi Grizzly,

I am trying to use Can Bus comm with B-G431B-ESC1 and I need help about this. Can you share your solution code / and hardware point?

Thank you.

Dear etempm,
it is currently a bit messy since I added something to the ESP32 version, but I will send you a direct message with the link. I am not a github pro, so we may need to tweak the accecss rights a bit if it does not work out of the box, but weā€™ll manage.

  • Chris

Thank you very much.