PDA

View Full Version : [Project] Jim and the Serializer - Part 2



JimH
02-20-2008, 08:09 PM
Let the programming begin!

At first I was a bit concerned that I would be able to start generating code and figure out how to make it talk to the serializer. Thanks to the recommendations from Alex in my Part 1 thread, I started over in my quest for understanding how to interface with it. Here's how it went:

Start simple, start free
One of the first links in Alex's original thread regarding programming was a video tutorial on the free Microsoft Visual C# Studio 2008 Express. Even though I have .NET Studio 2005 and Robotics Studio installed, I went ahead and download this version and installed/registered it. I then re-ran the Serializer .NET Library install. I have staying in this IDE so far and will remain there as long as it does what I need it to do.

Run the example
It took a little goofing around to get the server/gui up and running. Watching some of the tutorial videos helped with understanding the code/build/run/debug process so that I could get the programs running. I then entered the settings in the GUI and started making motors spin.

The example is configured to run the RoboticsConnection robot, but it does enough to play around with the serializer directly. It also gave me some clues on how to use the library, but wasn't clear enough for me to start modifying.

Read the instructions!
While trying to better understand how to utilize the library I went back to the documentation and ran through the example app at the end. It is a stand alone control application to play with the LEDs and set the foundation I needed to start making it my own.

A note on the documented example. Not sure what version of .NET Studio is was created for, but I needed to correct the lines that convert the values entered into the gui for the blink rate. The code example has a set of () after the value which is not correct. I also needed to right click the Serializer object reference in the line that assigns it to s_ and refactor it (I think).



private static Serializer s_;


Make the motors whir!
So before I stopped for the night...I fealt compelled to make the motor spin. Even more, I wanted to up the ante and make it 2 motors. I did this by adding some buttons and playing with making a motor spin when a button was clicked and stop when it was released. This proved tricky as the motor would start, but not stop. So after trying some different options, I added a start button and stop button for each motor. After tweaking the code a bit I was able to get this working.

What now?
I think it's time to add a sensor. I need to get some servo extension cables from the local hobby store so that I can hook up to the pins. Part of me wants to jump right into playing with the PING ))) sensor, but will control myself and rig up a bump sensor. Once I can get that working, I can then work on reactionary code.

Some questions
Is there anywhere to find code examples for the Serializer beyond the code provided by RoboticsConnection?
While the motors are fun to make work, it will be servos that are needed for the humanoid goal (long term). Is there any good explanation out there for how to interact with the servos at this level?

Thanks for the help and feedback so far.

Alex
02-22-2008, 05:12 PM
Hey Jim,

I wrote a small demo app (see attached) for you in C# 2005, so that you can see how to control servos with the Serializer. You should still be able to open it in 2008, but feel free to play around in 2005 (I still haven't upgraded yet, hehe). Sorry, but I didn't have time enough to document it like I would like to, but it's fairly straight forward so hopefully you can follow all of it. If you have any questions about it, don't hesitate to ask:)

I got all of my info (other than my programming skills) from these two pdf's:
http://www.roboticsconnection.com/multimedia/docs/SerializerWL_UserGuide_v2.1.pdf
http://www.roboticsconnection.com/multimedia/libraries/MSDNDocumentation/

Just in case you didn't see both of them.



Run the project and select a COM port from the dropdown menu at the top, then if all is connected correctly the controls on the form will enable. I'm using an older Serializer, but hopefully nothings changed much that will cause the program to crash. I'm going to be out of town till Sunday afternoon, so I'll check this thread when I get back.

JimH
02-23-2008, 07:14 PM
Hi Alex. Thanks for sharing the program. Unfortunately, when I download it and attempt to extract it I get an error that it is not a valid archive. Can you please reupload it? Also, I do have the docs you referenced. I have even gotten a servo to respond to manual code. Was just looking for some examples I could cut/paste and learn from.

Since posting this I have been continuing to make progress. I started to take apart a cheap RC vehicle that I had laying around and found that it had 2 gear reduction motors that drove it. So I stripped out the cheap RC controller and wired up the motors with the connectors that I used on the Serializer. I then mounted the project box I have the Serializer in to the vehicle and got it all wired up.

I have also switched to using Bluetooth to connect to the unit. So I now have a wirelessly controlled mobile platform.

I started out by attempting to get the form based program I had been using to test with to read the PING sensor and display the current readings, but was not successful. So I went to the demo app for the PING sensor that is in the MSDN style documentation, which is a console app. I was able to add in the motor control code and then some logic based on the distance reading from the PING sensor. Minutes later the little guy was driving around the den and bumping into things. I adjusted the code and got it working fairly well, but it still bumps into things to much. I need to add a bumper and a bump switch so that it doesn't beat my PING to death...

Here is the code I am using:



using RoboticsConnection.Serializer;
using RoboticsConnection.Serializer.Ids;
using RoboticsConnection.Serializer.Sensors;
using RoboticsConnection.Serializer.Components;
using RoboticsConnection.Serializer.Controllers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PINGSensorTest
{
class Program
{
static Serializer serializer;
static Ping ping;
private static PwmDCMotorController leftMotor;
private static PwmDCMotorController rightMotor;
static void Main(string[] args)
{
serializer = new Serializer();
serializer.PortName = "COM7";
serializer.BaudRate = 19200;
leftMotor = new PwmDCMotorController(serializer);
leftMotor.DCMotorId = DCMotorId.DCMotor1;
leftMotor.Speed = 0;
rightMotor = new PwmDCMotorController(serializer);
rightMotor.DCMotorId = DCMotorId.DCMotor2;
rightMotor.Speed = 0;
ping = new Ping(serializer);
ping.Pin = GpioPinId.Pin1;
ping.DistanceChangedThreshold = .2;
ping.UpdateFrequency = 40;
ping.DistanceChanged += new SerializerComponentEventHandler(ping_DistanceChang ed);
serializer.Run();

}
static void ping_DistanceChanged(SerializerComponent sender)
{
serializer.BlinkLED(LedId.Led1, 0);
serializer.BlinkLED(LedId.Led2, 0);
Console.WriteLine("Initalizing motion sequence...");
rightMotor.Speed = -40;
leftMotor.Speed = -40;
if (ping.Distance < 25)
{
Console.WriteLine("Initiate response program!");
rightMotor.Speed = 0;
leftMotor.Speed = 0;
System.Threading.Thread.Sleep(2000);
rightMotor.Speed = 50;
leftMotor.Speed = 50;
System.Threading.Thread.Sleep(400);
rightMotor.Speed = -60;
leftMotor.Speed = 60;
System.Threading.Thread.Sleep(2000);
}
}
}
}

Alex
02-25-2008, 10:18 AM
Unfortunately, when I download it and attempt to extract it I get an error that it is not a valid archive. Can you please reupload it? [...] Was just looking for some examples I could cut/paste and learn from.That's really strange... I just downloaded the zip and it worked just fine. I even tested it on my home and a couple of other work PC's. Maybe the zip didn't download all the way yet?

Anywoo, here's the code.

If you open a new C# windows form application in visual studio 2005, under the Solution Explorer, expand Form1.cs and click on Form1.designer.cs, select all of the code and replace it with this:


namespace MySerializerDemo
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer();
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.tsddbPorts = new System.Windows.Forms.ToolStripDropDownButton();
this.tsddbFirmware = new System.Windows.Forms.ToolStripDropDownButton();
this.vsbServoValue = new System.Windows.Forms.VScrollBar();
this.cmbServoID = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.toolStripContainer1.ContentPanel.SuspendLayou t();
this.toolStripContainer1.TopToolStripPanel.Suspend Layout();
this.toolStripContainer1.SuspendLayout();
this.toolStrip1.SuspendLayout();
this.SuspendLayout();
//
// toolStripContainer1
//
//
// toolStripContainer1.ContentPanel
//
this.toolStripContainer1.ContentPanel.Controls.Add (this.label2);
this.toolStripContainer1.ContentPanel.Controls.Add (this.label1);
this.toolStripContainer1.ContentPanel.Controls.Add (this.cmbServoID);
this.toolStripContainer1.ContentPanel.Controls.Add (this.vsbServoValue);
this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(439, 360);
this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Top;
this.toolStripContainer1.Location = new System.Drawing.Point(0, 0);
this.toolStripContainer1.Name = "toolStripContainer1";
this.toolStripContainer1.Size = new System.Drawing.Size(439, 385);
this.toolStripContainer1.TabIndex = 0;
this.toolStripContainer1.Text = "toolStripContainer1";
//
// toolStripContainer1.TopToolStripPanel
//
this.toolStripContainer1.TopToolStripPanel.Control s.Add(this.toolStrip1);
//
// toolStrip1
//
this.toolStrip1.Dock = System.Windows.Forms.DockStyle.None;
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsddbPorts,
this.tsddbFirmware});
this.toolStrip1.Location = new System.Drawing.Point(3, 0);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.Size = new System.Drawing.Size(142, 25);
this.toolStrip1.TabIndex = 0;
//
// tsddbPorts
//
this.tsddbPorts.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Tex t;
this.tsddbPorts.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsddbPorts.Name = "tsddbPorts";
this.tsddbPorts.Size = new System.Drawing.Size(66, 22);
this.tsddbPorts.Text = "COM Port";
this.tsddbPorts.TextImageRelation = System.Windows.Forms.TextImageRelation.TextAboveIm age;
//
// tsddbFirmware
//
this.tsddbFirmware.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Tex t;
this.tsddbFirmware.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsddbFirmware.Name = "tsddbFirmware";
this.tsddbFirmware.Size = new System.Drawing.Size(64, 22);
this.tsddbFirmware.Text = "Firmware";
//
// vsbServoValue
//
this.vsbServoValue.Enabled = false;
this.vsbServoValue.LargeChange = 1;
this.vsbServoValue.Location = new System.Drawing.Point(227, 73);
this.vsbServoValue.Minimum = -100;
this.vsbServoValue.Name = "vsbServoValue";
this.vsbServoValue.Size = new System.Drawing.Size(154, 98);
this.vsbServoValue.TabIndex = 1;
this.vsbServoValue.Value = -100;
this.vsbServoValue.Scroll += new System.Windows.Forms.ScrollEventHandler(this.vsbSe rvoValue_Scroll);
//
// cmbServoID
//
this.cmbServoID.Enabled = false;
this.cmbServoID.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.cmbServoID.FormattingEnabled = true;
this.cmbServoID.Location = new System.Drawing.Point(36, 88);
this.cmbServoID.Name = "cmbServoID";
this.cmbServoID.Size = new System.Drawing.Size(154, 28);
this.cmbServoID.TabIndex = 2;
this.cmbServoID.SelectedIndexChanged += new System.EventHandler(this.cmbServoID_SelectedIndexC hanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Comic Sans MS", 13F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(31, 60);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(151, 25);
this.label1.TabIndex = 3;
this.label1.Text = "Servo Motor ID";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("Comic Sans MS", 13F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.Location = new System.Drawing.Point(230, 36);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(174, 25);
this.label2.TabIndex = 4;
this.label2.Text = "Servo Motor Value";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(439, 383);
this.Controls.Add(this.toolStripContainer1);
this.Name = "Form1";
this.Text = "Alex\'s Demo App for Serializer";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this. Form1_FormClosing);
this.Load += new System.EventHandler(this.Form1_Load);
this.toolStripContainer1.ContentPanel.ResumeLayout (false);
this.toolStripContainer1.ContentPanel.PerformLayou t();
this.toolStripContainer1.TopToolStripPanel.ResumeL ayout(false);
this.toolStripContainer1.TopToolStripPanel.Perform Layout();
this.toolStripContainer1.ResumeLayout(false);
this.toolStripContainer1.PerformLayout();
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
this.ResumeLayout(false);

}

#endregion

private System.Windows.Forms.ToolStripContainer toolStripContainer1;
private System.Windows.Forms.ToolStrip toolStrip1;
private System.Windows.Forms.ToolStripDropDownButton tsddbPorts;
private System.Windows.Forms.ToolStripDropDownButton tsddbFirmware;
private System.Windows.Forms.VScrollBar vsbServoValue;
private System.Windows.Forms.ComboBox cmbServoID;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;

}
}



then, again in Solution Explorer, right click on Form1.cs, select "View Code", select all the code and paste this:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using RoboticsConnection.Serializer.Ids;
using RoboticsConnection.Serializer;
using RoboticsConnection.Serializer.Controllers;


namespace MySerializerDemo
{
public partial class Form1 : Form
{
Serializer serializer;
ServoMotorController smc;

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
string[] ports = System.IO.Ports.SerialPort.GetPortNames();

Array.Sort(ports);

int i = 0;

foreach (string s in ports)
{
tsddbPorts.DropDownItems.Add(s);

tsddbPorts.DropDownItems[i].Name = s;

((ToolStripMenuItem)tsddbPorts.DropDownItems[s]).CheckOnClick = true;
((ToolStripMenuItem)tsddbPorts.DropDownItems[s]).CheckedChanged += new EventHandler(Items_CheckedChanged);
i++;
}
}

void Items_CheckedChanged(object sender, EventArgs e)
{
bool b = ((ToolStripMenuItem)sender).Checked;

if (((ToolStripMenuItem)sender).Checked)
{
try
{
serializer = new Serializer();
serializer.PortName = ((ToolStripDropDownItem)sender).Name;
serializer.BaudRate = 19200;
serializer.StartCommunication();
smc = new ServoMotorController(serializer);


ServoMotorId[] smids = (ServoMotorId[])Enum.GetValues(typeof(ServoMotorId));

foreach (ServoMotorId smid in smids)
{
cmbServoID.Items.Add(smid.ToString());
}

cmbServoID.Enabled = true;
vsbServoValue.Enabled = true;
}
catch (Exception ex)
{
((ToolStripMenuItem)sender).Checked = false;
MessageBox.Show(ex.Message);
cmbServoID.Enabled = false;
vsbServoValue.Enabled = false;
}
}

tsddbFirmware.DropDownItems.Add("Version: " + serializer.GetFirmwareVersion());
}

private void vsbServoValue_Scroll(object sender, ScrollEventArgs e)
{
try
{
smc.Position = vsbServoValue.Value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
serializer.StopCommunication();
serializer.ShutDown();
}

private void cmbServoID_SelectedIndexChanged(object sender, EventArgs e)
{
smc.ServoMotorId = (ServoMotorId)Enum.Parse(typeof(ServoMotorId), cmbServoID.SelectedItem.ToString());
}
}
}

hopefully that works. Let me know if it doesn't:)

JimH
02-25-2008, 05:51 PM
That did the trick. Had to play around with it a bit and get the servo mapping chart out to hit the right pins, but it worked. Thanks for the help Alex!

roboticsconnection
02-26-2008, 03:08 PM
Alex,

Thanks for the support and example apps for Jim!

Jim,

Good job! :) Post some pics!

FYI...

I'm building a new 'Example Apps' (https://www.roboticsconnection.com/t-RoboticApplications.aspx)section on RoboticsConnection.com that will contain a lot of examples for using the Serializer with all of our libraries/services. I'm just now getting caught up from launching a new website, automating some backend processes, training new hires, and adjusting to a new baby in the house. :)

For 2008, I'm going to be dedicating a lot of time to buidling up the Example Apps section, which is way overdue. While the example source code in the Serializer .NET Lib MSDN documentation is useful, I'm sure customers would like to have some cool apps that perform useful tasks to learn from.

I'm also going to be selling some apps and libraries in this section (for very low prices) that are complimentary to both the .NET lib and MSRS Services, and hopefully build up a useful set of tools throughout the year.

I hope to get the section finished by the end of April, and new apps will trickle out there weekly.

Also, you can post on the RC forums (http://www.roboticsconnection.com/userForums/) too for technical support (I monitor those frequently). Of course, I'm not trying to pull you away from the awesome Trossen community forums, it's just a option for you. :)

Best Regards!

Jason Summerour
President,
Summerour Robotics Corp
Microsoft MVP
www.roboticsconnection.com (http://www.roboticsconnection.com)