Showing posts with label MATLAB. Show all posts
Showing posts with label MATLAB. Show all posts

Saturday, May 26, 2012

8Kb is not a lot

...but it just has to do.

The Arduino with the Atmega chip has only 8Kb bytes of RAM.  In writing my Arduino-MATLAB interface I came up hard against that limit.  My interface works by allowing a user to upload a small program to the Arduino that uses a locally defined function library.  I realized something was funny when programs will too many instructions failed.  This was because when program upload size exceeded a certain value, the Arduino would crash because it could no longer allocate memory for the incoming data.  By being more careful with memory, I was able to extend the amount I could send.

Also I found some nice ways to check the amount of memory available to malloc.  In the following code, x is there just to test that this function is working properly (i.e. detecting a prior malloc usage):


void funcFreeMem(IN_FREE_MEM_FUNC *in,OUT_FREE_MEM_FUNC *out)
{
  int sz = 0; 
  
  byte* x = (byte*) malloc(in->in * sizeof(byte));
  
  byte *buf;
  while ( (buf = (byte*) malloc (sz * sizeof(byte))) != NULL ) {
    sz++; // if allocation was successful, then up the count for the next try
    free(buf); // free memory after allocating it
  }
  
  free(buf);
  free(x);
  out->mem = sz;
}

Monday, March 19, 2012

MFC Control Complete

Today I finished implementing control over my mass flow controllers from Alicat.  I now have the capacity to drive two MFCs via analog voltage or serial from our custom Arduino shield.  Everything works directly from MATLAB.

This is our Arduino-based olfactometer control module connected to two Alicat MFCs.
The output works at high frequencies with the MFCs being able to follow up to 3 Hz well.  I doubt that this performance will be maintained with long downstream tubing, but I hope to be able to do at least 1 Hz at output.

I had to work out a kink to get switching between serial and analog control to work.  The Alicat documentation says that A$$W20=16384 should enable analog set point. However, I found that this does not work.  Reading register 20 after setting analog set point from the front panel, however, showed that the correct value is actually 17408.

The Arduino will start by default in analog control mode. To switch modes:

[mode] = {0: SERIAL_OUT, 1: ANALOG_OUT}
olf.funcALIMode([mode]);

I tested the whole setup using my handy dandy flowmeter and things work very well so far.  Here is the code I used for my current test setup:


olf = OlfactometerDriver_SerialInterface('COM10'); pause(12);


% proportional control var
olf.funcALIMessage('A$$W21=500')
% differential control var
olf.funcALIMessage('A$$W22=10')


olf.funcALISin(1,1,0.5);
olf.funcALISin(0,1,0.5);


Next step: connect the MFCs to the olfactometer, determine the right parameters for sinusoids, and verify output via PID.