Show Posts
|
|
Pages: [1] 2
|
|
2
|
Topics / Science and Measurement / Re: Leonardo Response Box (Reaction Time)
|
on: November 01, 2012, 07:26:52 am
|
|
About 1 ms accuracy would be enough.
The arduino does not have to know when the stimulus is pressed. Software measures the time from stimulus onset until key press on a keyboard, or on the response box (the arduino).
A better idea (more accurate) would be sincronize Arudino and PC clocks and then have the arduino record exact keypress and keyrealease time, and just send a char with a timestamp.
But then I would need a special driver for the device, and special software to use it.
I'd like to keep things simple and just make the arduino emulate a keyboard.
|
|
|
|
|
3
|
Topics / Science and Measurement / Re: Leonardo Response Box (Reaction Time)
|
on: October 24, 2012, 05:27:58 pm
|
|
Oh, by the way, RT is usualy measured from stimulus onset (e.g. a picture on the screen) to key press.
Or, if the subject keeps one button pressed and reacts with another button, then there are two times - from stimulus onset to key1_release, and from key1_release to key2_press.
|
|
|
|
|
4
|
Topics / Science and Measurement / Leonardo Response Box (Reaction Time)
|
on: October 24, 2012, 05:22:28 pm
|
Hello, Reaction time experiments are widely used in psychology. For serious use, it's important to have a very accurate measuring device. Standard keyboards are not made with timing accuracy in mind, so psychologists use special 'response boxes', such as this one: http://www.pstnet.com/hardware.cfm?ID=102 It's very accurate, but it works only with special software, connects via serial port, needs drivers, and - it's pricey. I'm guessing the new Leonardo could be made into a nice, accurate reaction time measuring device. The most user-friendly way would be to make leonardo emulate a keyboard, so it could be simply plugged in. Also, some low-bounce buttons should be used. So, does someone know lag-times for the leonardo - how much time does it take from pressing a button on the arduino to computer receiving the button-press signal? If it is long - could it be made shorter? How about low-bounce button designs? Thank you.
|
|
|
|
|
5
|
Topics / Robotics / PCT Robot arm, only control loops, no inverse kinematics
|
on: October 16, 2012, 05:45:12 am
|
Hello, I've built a robot arm (using OWI 535, 4 deg. of freedom) that uses a hierarchy of control loops for positioning - there is no inverse kinematics. There are three levels of control. The first level controls the speed of the motors using potentiometers as sensors. The second levels loops control the angles of each joint. Loops on the third level coordinate second level loops in complex movements such as extending reach while maintaining hand pitch. It's based on PCT (perceptual control theory) and a fascinating virtual model of a human arm ( http://www.billpct.org/ after dl, look for Coordination Demo) I'ts primary purpose is modeling the human nervous system, and since there is no inverse kinematics, just simple control loops, it might be useful elsewhere. The control loops are currently simulated on the computer. An arduino collects sensor data and sends it to the computer, and receives motor speed commands and sends them to motors. It might also be possible to do all the calculations on the arduino itself (but then I'd need more analog inputs). The software is written in C#. So.. it's working. I'm planing a more complex arm. I'd be happy to answer any questions.
|
|
|
|
|
6
|
Using Arduino / Interfacing w/ Software on the Computer / Re: Need faster serial transfer - Arduino and C#
|
on: April 25, 2012, 03:54:28 pm
|
btw. Is there an 'edit post' in this forum? a little correction: while (AppStillIdle) { while (stopwatch.ElapsedMilliseconds < 5) { ; } label31.Text = Angle[0].Position.ToString() + " " + Angle[1].Position.ToString() + " " + Angle[2].Position.ToString() + " " + Angle[3].Position.ToString() + " " + temperature.ToString(); label1.Text = stopwatch.ElapsedMilliseconds.ToString("D3"); if (serialPort1.IsOpen) { label32.Text = serialPort1.BytesToRead.ToString(); serialPort1.Write("WWWWW"); } stopwatch.Reset(); stopwatch.Start(); }
|
|
|
|
|
7
|
Using Arduino / Interfacing w/ Software on the Computer / Re: Need faster serial transfer - Arduino and C#
|
on: April 25, 2012, 03:50:30 pm
|
@PaulS Wonderfull! I've combined your advice with what I have now, works like a charm! I've managed to get it down to 7ms per cycle, but I'll be using 10ms because of some calculations that need to be done. Thank you very much, the bit about not calling new threads or event handlers for every serial data receive helped the most! So, now I have a gui update thread and a serial read thread. Here's the working code, the important parts, if anyone else needs it. Questions (or suggestions) are wellcome: The gui update thread: public MainForm() { InitializeComponent(): Application.Idle += new EventHandler(MainLoop); }
private void MainLoop(object sender, EventArgs e) { while (AppStillIdle) { while (stopwatch.ElapsedMilliseconds < 10) { ; } label31.Text = Angle[0].Position.ToString() + " " + Angle[1].Position.ToString() + " " + Angle[2].Position.ToString() + " " + Angle[3].Position.ToString() + " " + temperature.ToString(); if (serialPort1.IsOpen) { serialPort1.Write("WWWWW"); // just a test signal } } private bool AppStillIdle { get { NativeMethods.Message msg; return !NativeMethods.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0); } } // snip
class NativeMethods { /// MainLoop helper class, found it here: /// http://blogs.msdn.com/b/tmiller/archive/2005/05/05/415008.aspx
[StructLayout(LayoutKind.Sequential)] public struct Message { public IntPtr hWnd; public UInt32 msg; public IntPtr wParam; public IntPtr lParam; public uint time; public System.Drawing.Point p; } [System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool PeekMessage(out Message msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags); }
the serial reader thread private Thread readThread = null;
private void StartSerialButton_Click(object sender, EventArgs e) { try { serialPort1.Open(); StartSerialButton.Enabled = false; stopwatch.Start(); first = true; readThread = new Thread(new ThreadStart(this.Read)); readThread.Start(); serialPort1.Write("WWWWW");
} catch { System.Windows.Forms.MessageBox.Show("Could not opet COM5", "Error!"); } }
public void Read() { while (serialPort1.IsOpen) { if (serialPort1.BytesToRead >= 12) { byte[] SI = new byte[12]; serialPort1.Read(SI, 0, 12); this.ReadValues(SI); } } }
private void ReadValues(byte [] SI) { for (int i = 0; i < 4; i++) { Angle[i].Position = SI[i * 2 + 1] | (SI[i * 2 + 2] << 8); } temperature = SI[9] | (SI[10] << 8); }
|
|
|
|
|
9
|
Using Arduino / Interfacing w/ Software on the Computer / Re: Need faster serial transfer - Arduino and C#
|
on: April 25, 2012, 12:54:04 pm
|
I'm thinking that the biggest problem is on the C# side and the separate serial threads. My knowledge on threads is low. Here's the code: public MainForm() { InitializeComponent();
serialPort1.BaudRate = 57600; serialPort1.PortName = "COM5"; serialPort1.ReceivedBytesThreshold = 12; stopwatch.Start(); Application.Idle += new EventHandler(MainLoop); }
private void MainLoop(object sender, EventArgs e) { if (DataReceived) { label31.Text = stopwatch.ElapsedMilliseconds.ToString(); DataReceived = false; stopwatch.Reset(); stopwatch.Start(); } } private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { serialPort1.Read(SI, 0, 12); this.Invoke(new EventHandler(ReadPots)); } private void ReadPots(object sender, EventArgs e) { for (int i = 0; i < 4; i++) { Angle[i].Position = SI[i * 2 + 1] | (SI[i * 2 + 2] << 8); }
temperature = SI[10] | (SI[11] << 8); DataReceived = true; }
|
|
|
|
|
10
|
Using Arduino / Interfacing w/ Software on the Computer / Re: Need faster serial transfer - Arduino and C#
|
on: April 25, 2012, 12:45:49 pm
|
Thank you for your replies. @elsupremo yes, the num is 4 chars long (I set it to 4 only after having the error you described I've set the baud rate to 57600. That part works good. Even the 115200 works and I haven't seen any errors. @robtillaart Output messages from arduino are analog readings (0-1023), so two bytes are needed. And you're right, pwm values can be placed in only byte. I can even cram the direction values to one byte, so plus 4 pwm values, that's only 5 bytes. The two loops you mention are intentionaly different. The reading loop has 4 chunks of data to read - motor direction and speed. The printing loop has 5 chunks from analog pins - four are potentiometer readings, and one is a thermistor reading. ---- More questions: 1. Would it be advisable not to use the start and stop bytes, just raw messages? 2. Does anyone know of a way to speed up C# serial communication? The fastes I can get it to run using DataReceived event is 15 ms. I'm googleing as we speak, but nothing seems to be working. by the way, I've found an elegant way of converting integers to bytes: byte output [12]; // snip
for (int i=0;i<5;i++) { int x=analogRead(i); output[1+2*i] = x & 0xFF; output[2+2*i] = (x >> 8) & 0xFF; } Serial.write(output,12); On the C# side, the code is: byte [] SI = new byte[12]; // formated as '0aabbccddee0' // snip
serialPort1.Read(SI, 0, 12); for (int i = 0; i < 4; i++) { Angle[i].Position = SI[i * 2 + 1] | (SI[i * 2 + 2] << 8); }
temperature = SI[10] | (SI[11] << 8); DataReceived = true;
Currently I'm having trouble
|
|
|
|
|
12
|
Using Arduino / Interfacing w/ Software on the Computer / Re: Need faster serial transfer - Arduino and C#
|
on: April 23, 2012, 06:54:49 pm
|
The baud rate is 28800. I've tried raising it, but i haven't seen much, if any, improvement. I'm sending ASCII data. Would it make much difference to change it to bytes? Here's some code to see what I'm doing: Computer output message is formated as "XDPPPDPPPDPPPDPPP\n" where X is start signal, D is 0,1,2 indicating direction of motor movement and PPP is a pwm signal value for a motor. if (Serial.available() >= 18) { c = Serial.read(); if (c=='X') { for (int i=0; i<4; i++) { Direction[i] = Serial.read(); num[0]=Serial.read(); num[1]=Serial.read(); num[2]=Serial.read();
Speed[i] = atoi(num); } c=Serial.read();
SetPins(); PrintPots(); } void PrintPots() { Serial.print ("X"); for (int i = 0; i<5;i++) { PrintFormated(pot[i]); if (i<4) Serial.print(" "); } Serial.print ('\n'); }
void PrintFormated (int x) { if (x < 100) Serial.print ('0'); if (x < 10) Serial.print ('0'); Serial.print (x); }
Arduino output messages are formated as "X### ### ### ### ###\n" This is C# code: serialPort1.BaudRate = 28800; serialPort1.PortName = "COM5"; serialPort1.ReceivedBytesThreshold = 21;
//..snip
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) {
if (ClosePort) { serialPort1.WriteLine(NullSignal); serialPort1.Close(); } else { this.BeginInvoke(new EventHandler(ReadPots)); } }
private void ReadPots(object sender, EventArgs e) { SerialInput = ""; try { SerialInput = serialPort1.ReadLine(); } catch { label31.Text = "READ FAILED"; return; } DataReceived = true;
label1.Text = SerialInput;
if (SerialInput[0] == 'X') // All messages are formated as "X### ### ### ### ###\n" { String[] values = SerialInput.Split('X', ' ', '\n'); for (int i = 0; i < 4; i++) { Angle[i].Position = Convert.ToDouble(values[i + 1]); }
|
|
|
|
|
13
|
Using Arduino / Interfacing w/ Software on the Computer / Need faster serial transfer - Arduino and C#
|
on: April 23, 2012, 06:20:27 pm
|
|
Hello, I'm new to arduino and serial protocol. I've made a program in C# to communicate with arduino - reading pot values and sending commands for motor movements. My problem is that I would need faster serial transfer. It's averaging about 15 ms per send-receive cycle. Only 20 bytes are sent and then 20 bytes received. Is this normal or can it go faster?
|
|
|
|
|
14
|
Topics / Robotics / Stabilise potentiometer readings?
|
on: April 23, 2012, 06:16:05 pm
|
|
I'm using a 5k pot as an angle sensor for a robor arm joint, but I'm getting unstable readings (+- 2) Software averaging is ok, but I would need to do it in hardware. Is this the best that can be done, or can I improve it somehow, by adding some capacitors (which ones) or perhaps using a lower resistance potentiometer?
|
|
|
|
|