Forum Replies Created
-
AuthorPosts
-
Rich ChampeauxParticipantGreat, I’m glad I was of help. I’m new to the open source scene, so I don’t know all the etiquette and protocol and didn’t even think about the possibility of fixing it myself. I will have to read up on pull requests on github. Also, I found it only through code inspection and looking for inconsistencies, not because I knew what it was supposed to do.
However, what about the second issue I identified? It looks like you are trying to read a byte, clear a bit, and then write it back. However you are not reading and writing from the same place. You are reading from “port” and writing to “UartStatusOffset+port”
I would like to understand more about the lower level interactions with the devices. Where are you getting your information about how to communicate with the devices?
- This reply was modified 10 years, 10 months ago by Rich Champeaux.
Rich ChampeauxParticipantI think I found the problem. I don’t really know the code, so I’m just tracing through and looking at how the Port number is used, but…
UARTSensor.InitUart() goes into a loop where it calls ClearPortChanged(), waits, and then reads the status and checks the status for the UartPortChanged bit.
GetStatus() is implemented as such:
private byte GetStatus()
{
return uartMemory.Read(UartStatusOffset, NumberOfSenosrPorts)[(int)port];
}And basically reads the status byte from memory location “UartStatusOffset+port”
However, ClearPortChanged() has a bug I think. Its implemented as:
private void ClearPortChanged()
{
SensorManager.Instance.ClearUartPortChanged(this.port);
uartMemory.Write (UartStatusOffset, new byte[] { (byte)(uartMemory.Read ((int)port, 1) [0] & ~UartPortChanged) });
this.uartMode = UARTMode.Mode0;
}The uartMemory.Write() call doesn’t look right. It reads one byte from memory location “port” (not “UartStatusOffset+port”, just “port”), clears the UartPortChanged bit in the byte, and then writes it to memory location “UartStatusOffset” (not “UartStatusOffset+port”)
So the first problem that I see, is that it is always writing one byte to memory location “UartStatusOffset” regardless of the port number (which means it always writes to the port 1 location). The second possible problem is that the value it reads before clearing the bit is from memory location “port”, not “UartStatusOffset+port” that it’s supposed to be writing to and that it reads from in GetStatus().
I hope this helps. I’m going to try it myself tonight.
- This reply was modified 10 years, 10 months ago by Rich Champeaux.
Rich ChampeauxParticipantAnders,
Thanks for the quick response.
Rich ChampeauxParticipantJacek S,
I found the source on github. Thanks.With Resharper, all I have to do is ctrl-click on a symbol and it takes me to the definition. If the definition is from a DLL, instead of my own source, then it automatically decompiles the assembly into C# code.
It’s rather handy for debugging stuff, but the downside is that it makes up names for local variables, and you end up with a local variable named “flag1” instead of “moveBackwards”. So it’s nice to have the real source code. Also, having the solution means I can tweak the code myself when I hit a roadblock.
- This reply was modified 10 years, 11 months ago by Rich Champeaux.
Rich ChampeauxParticipantI think I’ve also figured out why the MoveTo() calls to move my medium motor return immediately. I do a MoveTo() with a speed of 100 and a position of 2160 (6 rotations). As I trace through the code, I discovered that MoveTo() calls On(speed, degrees, brake, waitForCompletion), which calculates a ramp up and ramp down step count. However, since my number of steps is so high (2160), it creates a large rampUpSteps of 324 steps.
I think the large ramp up time, coupled with a delay I noticed when starting the motors, is responsible for WaitForMotorToStop() not working correctly. WaitForMotorToStop() is implemented as follows:
protected virtual void WaitForMotorToStop()
{
Thread.Sleep(300);
do
{
Thread.Sleep(50);
}
while ((int) this.output.GetSpeed(this.PortList[0]) != 0);
}I think that the large ramp up time and the start-up delay I’ve noticed results in the speed still being 0 after the 350 ms that WaitForMotorToStop() waits before it checks the speed. Therefore it thinks the motor has already stopped when it hasn’t actually started moving.
Before looking at the source code I had tried directly using the SpeedProfileStep() method and specifying the ramp up of only 50 steps. This worked better but was still unreliable. The first time I called it, it always failed to wait. Subsequent calls would usually wait, but occasionally wouldn’t. I’m guessing that the first time, the start-up delay is longer for some reason, and for subsequent calls, it’s right on the edge of the 350 ms.
Anyhow, now that I can see what’s going on inside MonoBrickFirmware.dll, I can work around the issues I’m having. I think I’ll make my own MoveTo method that checks the tacho first to make sure the motor has started moving before it checks the speed to see if it’s stopped.
Rich ChampeauxParticipantSo I used Resharper to decompile MonoBrickFirmware.dll and I’ve figured out why MotorSync.On(speed, turnRatio) never returns. It’s calling the On(speed, turnRatio, degrees, brake, waitForCompletion) overload and is passing “true” for waitForCompletion. Therefore it will never return.
public void On(sbyte speed, short turnRatio)
{
this.On(speed, turnRatio, 0U, false, true);
}public void On(sbyte speed, short turnRatio, uint degrees, bool brake, bool waitForCompletion = true)
{
this.StepSync(speed, turnRatio, degrees, brake, waitForCompletion);
if (!waitForCompletion)
return;
this.WaitForMotorToStop();
}So, I can just use the 5 parameter overload instead of the two parameter one.
- This reply was modified 10 years, 11 months ago by Rich Champeaux.
-
AuthorPosts
Follow