String to Hexadecimal to UInt32??

Post questions and issues with Concept2 PM3 SDK
Post Reply
soares
Paddler
Posts: 17
Joined: April 18th, 2006, 6:30 pm
Location: Portugal

String to Hexadecimal to UInt32??

Post by soares » August 24th, 2006, 7:18 am

Hello again :D

Now i need to pass the value in a string (which represents a Hexadecimal value) to a UInt32 variable.

I´m asking the user to insert a distance in the application, and then i´m converting the value to Hexadecimal, then splitting the value, and then adding the 0x to the hexa values. Now i need to put the values into the UInt32[] cmd_data to send to the machine, but i´m having difficulties doing this.

I have this so far:

Code: Select all

 UInt32 uiDecimal = 0;
                int s = 21;
                Convert.ToUInt32(s);

                try
                {
                    // Convert text string to unsigned integer
                    uiDecimal = checked((UInt32)System.Convert.ToUInt32(this.textBoxNum.Text));
                }

                catch (System.OverflowException exception)
                {
                   
                }

                                         
                string var = String.Format("{0:x}", uiDecimal);
                
                string[] idUser1 = new string[3];
                
                idUser1[0] = var.Remove(1);

                idUser1[1] = var.Substring(1);

                string num1 = "0x" + idUser1[0].ToString();                
                string num2 = "0x" + idUser1[1].ToString();
Can anyone help me?

Rui

haboustak
500m Poster
Posts: 77
Joined: March 17th, 2006, 3:02 pm
Location: Cincinnati

Post by haboustak » August 24th, 2006, 11:02 am

Rui,

Number bases don't work that way. An integer is an integer and it can be displayed in base-10 (decimal) or base-16 (hex) or even base-8 (octal) or base-2 (binary). It's all the same number and it's all stored the same way inside a UInt32.

The "0x" prefix that we use to denote hex numbers is just a compiler convenience, so that it knows how to interpret the digits. You don't need that prefix in order for the number to "become hex". Hex itself is just one way to display numbers to humans so we can read them (decimal is another).

Ok, so to do what you want to do.
1: You have a string that represents a distance (from Textbox.Text)
2: You convert it to an integer using Convert or UInt32.Parse()
3: You split that 32-bit integer up into byte-sized components
4: You place the split integers into the CSAFE frame one byte at a time

Code: Select all

   String str_number = "2000"; // 2K

   // Convert the String to an integer
   // Decimal: 2000
   // Hex: 0x07D0
   UInt32 i_number = UInt32.Parse(str_number); 

   //  Now split that up for the CSAFE frame
   //  CSAFE_SETHORIZONTAL_CMD needs two bytes LSB and MSB
   UInt32 distance_lsb = (i_number & 0xFF); // LSB: 0xD0
   UInt32 distance_msb = ((i_number >> 8) & 0xFF); // MSB: 0x07
   UInt32 distance_unit = 0x24; // CSAFE meters

   //  Put it into the CSAFE frame
   cmd_data[cmd_len++] = distance_lsb; // LSB: 0xD0
   cmd_data[cmd_len++] = distance_msb; // MSB: 0x07
   cmd_data[cmd_len++] = distance_unit; // Meters: 0x24

  //  Send it off
  tkcmdsetCSAFE _command(...)
The important thing here is understanding how to split or combine integers. You might want to read a bit about the differences between byte/short/long integer types and how they're stored. The PM3 uses a short integer (two-bytes) to represent horizontal distance. The above code 'chops' the bottom two bytes out of the 32-bit distance value and stores them into the CSAFE frame. You can use similar binary operations to assemble a short integer from two bytes (e.g. convert 0x07 and 0xD0 to 0x07D0)

The CSAFE library is confusing because a command is defined as an array of 32-bit integers (cmd_data). But the CSAFE protocol deals with single byte messages, so each index into the cmd_data array can only store one byte. The top 3 bytes of each element of cmd_data is 0x00. To transmit a short or long value you have to split it up into multiple slots of the command array. One slot per byte of data. CSAFE_PM_GET_WORKDISTANCE, for example, returns a 32-bit integer and requires 4 slots of cmd_data to store the 4 byte components.

Hope that makes sense. It probably doesn't.

Mike

soares
Paddler
Posts: 17
Joined: April 18th, 2006, 6:30 pm
Location: Portugal

Post by soares » August 24th, 2006, 6:46 pm

Actually now all makes sense :D

I wasn´t understanding the hexa thing because i was doing some tests and i wasn´t able to send the commands in Hexa without the prefix 0x, i knew this was only for showing but as wasn´t getting there, i thought it had to be that way.
So the only way i knew of doing that was by spliting strings and adding the prefix and the trying to put it in the cmd_data var.

Now i understand, i only need to split numbers that dont fit in one slot, and they dont have to be in hexadecimal.

After you put your example i was able to do the distance method and the time method that doesn´t need to split anything.

Again thanks a lot for your help Mike, you sure know a lot about programming, and you explain very well.

PM: Another thing i tried to do and i´m having difficulties is after a training has been completed to reset the PM3 and send it back to main menu.
I´v tried the reset, the goFinished, the goIdle and the goReady and nothing happens.

soares
Paddler
Posts: 17
Joined: April 18th, 2006, 6:30 pm
Location: Portugal

Post by soares » August 30th, 2006, 1:17 pm

Hey Mike, sorry to be disturbing you again.

I´m really a noob :cry: :cry:

The only problem i have now to finish my project is that i cant send the PM3 back to the Main Menu when a training is finished.

i´ve tried the goIdle, the goReady, every go... in the book. and combinations of them but without success.

My problem is that when a user finishes his training, the data is still showing in the PM3, and when i try to set another training, the PM3 shows the new data set, but with the getDistance and getWork, i get the last data of the last user and so the new training wont start.

So i need some kind of reset (I´ve tried to send a reset cmd) so that when a new user sets his training is works fine.

Thanks

Rui

soares
Paddler
Posts: 17
Joined: April 18th, 2006, 6:30 pm
Location: Portugal

Post by soares » August 30th, 2006, 2:05 pm

Never mind!

I found the answer :D

I only needed to do a goIdle and a goHaveID.

Now it works OK.

haboustak
500m Poster
Posts: 77
Joined: March 17th, 2006, 3:02 pm
Location: Cincinnati

Post by haboustak » August 30th, 2006, 2:25 pm

Rui,

All of the GO_ commands affect the PM3's CSAFE state machine. Unfortunately, unless you actually use the state machine to put the PM3 into the correct state you won't be able to use them. You should also note that the GO_ commands don't consistently update the PM3 display as you might expect. You have to issue them in a specific order (based on the current state).

If the user starts rowing when the PM3 is in the READY state, the state machine transitions to the OFFLINE state and you can no longer do anything but watch the progress (no GO_ commands will work).

What I consider the best way to manipulate the state machine into doing what you want is:
1: Start from the READY state
3: Setup workout
4: Issue GO_INUSE
5: Wait for workout to complete
6: Issue GO_IDLE
7: Issue GO_READY

The IDLE state is the 'default' CSAFE state when a machine is under remote control. It requests the user to enter their CSAFE ID, which can be recorded by a central server. You probably don't need the user to record a certain ID, so you can skip the IDLE state when starting a workout. Unfortunately, if you skip the IDLE state when exiting the FINISHED state, the PM3 transitions to READY but doesn't update the screen. So you have to hit the IDLE state for a moment on your way out of FINISHED.

You should track the status byte returned by CSAFE to determine what state the rowing machine is in currently. This will allow you to ensure that the state transitions are happening (either on command or automatically by the PM3)

I've verified that the GET_STATUS_CMD doesn't work with new firmware. It returns a 0-byte response frame. So you'll need to look for a STATUS byte that's sent along with a CSAFE response to a different command (e.g. GO_HAVEID, etc) in order to monitor the current state of the machine.

Maybe that will work. I really haven't tested the state machine much since the firmware was out of the 80s.

Mike

soares
Paddler
Posts: 17
Joined: April 18th, 2006, 6:30 pm
Location: Portugal

Post by soares » August 30th, 2006, 4:46 pm

i really didn´t understand why the GETSTATUS always returned 0, i was thinking of using it to know the staus of the machine so that i could folow the State Machine Diagram, but as i was unable to know the status i figured that when the user ends the session it stays in Finished and so i needed to send it to Idle.
The thing is that when i sent it goIdle after is finished, the PM3 asked for the User ID and i didnt understand why. I tried to send the GOHAVEID before the GOIDLE but it didn´t work, so, i tried to send the GOHAVEID after the GOIDLE and it worked fine.

I´m folowing all your steps but the last GOREADY. But i´ll put in the code.

I should have used the status byte in other commands to know the status, but it´s too hot in Portugal at the moment and my head is burning :D
and i should practice more often my programming to pay more attention to this little things that can help me, my programming skills are a bit green.

Thanks a lot

Rui

haboustak
500m Poster
Posts: 77
Joined: March 17th, 2006, 3:02 pm
Location: Cincinnati

Post by haboustak » August 30th, 2006, 5:15 pm

You're making good progress. It sounds like you've got a nearly functional application on your hands.

The Concept2 SDK documentation is jam packed with information, and it can be a little tough to take it all in at once. Plus, it's written like an engineering datasheet, so it's not exactly a beginner's document. You could argue that it's more suited to a systems programmer than an application programmer.

We'd certainly benefit from a couple well written tutorials on getting started that follow the same path you've been taking for the past couple weeks.

Mike

Post Reply