Archive for the ‘Uncategorized’ Category.

Serial IO in VisualStudio 2011 / C++

I needed to hack together a quick windows application to read data over a serial port and write it to a file. Unfortunately I think VisualStudio is probably still the best way of writing Win32 GUI apps. However I’ve not really used VisualStudio since the VisualStudio.net beta, and most of the stuff I did before that was on VisualStudio 6.

Man Microsoft have really murdered C++… are these proprietary garbage collection extensions all over the place? I couldn’t see a way of writing a pure C++, unmanaged GUI app in VS 2011…

Anyway, to get Serial IO working in a GUI application I needed to add the following methods, these were all added to the Form itself, like I say this was a quick hack:

public:
	// members
	String^ comport;
	String^ dump_filepath;
	String^ current_filename;
	SerialPort^ serialn;

	// initalise serial port
	void init_acquire() {
		int baudRate=9600;

		serialn = gcnew SerialPort(comport, baudRate);

		serialn->ReadTimeout = 50;

		serialn->Open();
	}

	// Read from serial port
	String^ acquire() {;
		String^ s;
		try {
			s = serialn->ReadLine();
		}
		catch (TimeoutException ^) { }
		
		return s;
	}

	// Button handler, starts thread
	private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {

		dumped_lines      = 0;
		dumped_file_count = 0;
		dump_filepath = this->drop_location_textbox->Text;
		current_filename = dump_filepath + dumped_file_count + ".txt";

		comport = comport_textbox->Text;

	    ThreadStart ^myThreadDelegate = gcnew ThreadStart(this, &Form1::repeat);
		trd = gcnew Thread(myThreadDelegate);
		trd->IsBackground = true;
		trd->Start();
		dumped_lines = 0;
	}

	// Thread code
	delegate void DelegateThreadTask();
	private: void ThreadTask() {

		// This weirdness is required because setting the TextBox text is not thread safe.
		if (data_textbox->InvokeRequired == false) {
			String ^data = acquire();
			this->data_textbox->Text = this->data_textbox->Text + data;
			//current_filename

			StreamWriter^ sw = gcnew StreamWriter(current_filename,true);

			sw->WriteLine(data);

			sw->Close();

		} else {
			DelegateThreadTask ^myThreadDelegate = gcnew DelegateThreadTask(this,&Form1::ThreadTask);
			this->Invoke(myThreadDelegate);			
		}
	}

	// Thread loop (reads from serial, dumps to file/textbox.
	private: void repeat() {
		init_acquire();
		while(true) {
			ThreadTask();
			Thread::Sleep(100);
		}
	}

You’ll also need to add the following headers:

	using namespace System::IO::Ports;
	using namespace System::Threading;
	using namespace System::IO;

SDL_BlitSurface causes memory leak on MacOS X

When I use SDL_BlitSurface on Mac OS X it seems to cause a memory leak, it’s probably in some way related to the way I’m using Blit but anyway I needed a quick hack to get round the problem, performance is not really an issue so I just wrote a function to write the points to the screen one by one:

There are a bunch of things this version doesn’t do that SDL_BlitSurface does, so beware. It ignores src_rec (just like SDL_BlitSurface would if it were NULL), and it does no conversion to insure source and dest are the same format (so you’ll have to convert the surfaces first).

void SlowBlitSurface(SDL_Surface *source,SDL_Rect *src_rec,SDL_Surface *dest,SDL_Rect *dest_rec) {

  int sbpp = source->format->BytesPerPixel;
  int dbpp = dest->format->BytesPerPixel;
  for(size_t x=0;x<source->w;x++) {
    for(size_t y=0;y<source->h;y++) {
      Uint8 *p = (Uint8 *)source->pixels + (((y * source->w) + x) * sbpp);
      Uint32 pval = *(Uint32 *) p;
      Uint8 *d = (Uint8 *)dest->pixels   + ((((dest_rec->y+y) * (dest->w)) + (dest_rec->x+x)) * dbpp);
      *((Uint32 *) d) = pval;
    }
  }
}

HTML Canvas simple example

<html>
<head>

<script type="text/javascript">

  function draw_rect(x,y) {
    var canvas = document.getElementById("m_canvas");
    if(canvas.getContext) {
      var ctx = canvas.getContext("2d");
      ctx.fillStyle = "rgb(200,0,0)";
      ctx.fillRect(x,y,5,5);
    }
  }

  function onMouseMove(evt) {
    draw_rect(evt.pageX,evt.pageY);
  }

  window.onmousemove = onMouseMove;

</script>


</head>

<canvas id="m_canvas" width="800" height="600">You need a better web browser.</canvas>

</body> 
</html> 

Gumstix serial device emulation

Once you have the kernel built for peripheral mode, getting the gumstix to emulate a serial port is pretty straight forward, just load the g_serial module. This will create a device called /dev/ttyGS0.

modprobe g_serial
cat /dev/random > /dev/ttyGS0

I could get about 3.5 Kilobytes a second over the link.

You can also use g_multi to get serial and mass storage at the same time:

modprobe g_multi file=/file_store_data