How is defined the data type FXPT2DOT30 in the BMP file structure? - bmp

The type FXPT2DOT30 appears in defining the struct CIEXYZ for BMP files,
according to the definition provided by Microsoft:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd371828(v=vs.85).aspx
However, I cannot found the exact definition of FXPT2DOT30 anywhere.
Which is its precise definition?
What kind of data is supposed to hold?

#RobinGreen provided a link:
There it is the answer to my question:
[...] FXPT2DOT30 [...] which means that they are interpreted as fixed-point values with a 2-bit integer part and a 30-bit fractional part.

According to fileformat.info here is an unpacked version of the BITMAPV4HEADER structure. The fields between CSType and GammaRed correspond to the CIEXYZTRIPLE bV4Endpoints in BITMAPV4HEADER.
typedef struct _Win4xBitmapHeader
{
DWORD Size; /* Size of this header in bytes */
LONG Width; /* Image width in pixels */
LONG Height; /* Image height in pixels */
WORD Planes; /* Number of color planes */
WORD BitsPerPixel; /* Number of bits per pixel */
DWORD Compression; /* Compression methods used */
DWORD SizeOfBitmap; /* Size of bitmap in bytes */
LONG HorzResolution; /* Horizontal resolution in pixels per meter */
LONG VertResolution; /* Vertical resolution in pixels per meter */
DWORD ColorsUsed; /* Number of colors in the image */
DWORD ColorsImportant; /* Minimum number of important colors */
/* Fields added for Windows 4.x follow this line */
DWORD RedMask; /* Mask identifying bits of red component */
DWORD GreenMask; /* Mask identifying bits of green component */
DWORD BlueMask; /* Mask identifying bits of blue component */
DWORD AlphaMask; /* Mask identifying bits of alpha component */
DWORD CSType; /* Color space type */
LONG RedX; /* X coordinate of red endpoint */
LONG RedY; /* Y coordinate of red endpoint */
LONG RedZ; /* Z coordinate of red endpoint */
LONG GreenX; /* X coordinate of green endpoint */
LONG GreenY; /* Y coordinate of green endpoint */
LONG GreenZ; /* Z coordinate of green endpoint */
LONG BlueX; /* X coordinate of blue endpoint */
LONG BlueY; /* Y coordinate of blue endpoint */
LONG BlueZ; /* Z coordinate of blue endpoint */
DWORD GammaRed; /* Gamma red coordinate scale value */
DWORD GammaGreen; /* Gamma green coordinate scale value */
DWORD GammaBlue; /* Gamma blue coordinate scale value */
} WIN4XBITMAPHEADER;

From gdiplus.h:
typedef long FXPT2DOT30, FAR *LPFXPT2DOT30;
typedef struct tagCIEXYZ
{
FXPT2DOT30 ciexyzX;
FXPT2DOT30 ciexyzY;
FXPT2DOT30 ciexyzZ;
} CIEXYZ;

Related

Newbie X11 double buffering coding help request

I botched together the following code to do a simpler rotating radar display.
q1) How can I eliminate the flicker of the line being drawn and then drawn over. Can I use double buffering somehow ?
q2) How can I get Mouse and Keyborad inputs and process/parse them.
My goal is to read angle and distance data from an ultrasonic sensor and display that as a sweep. This data comes from an Arduino with an ultrasonic rangefinder mounted on a servo sweeping backwards and forwards 180 Deg. I also cant quite get the math right. I'd like it to go from 0 to 180, left to right and back depending on the angle data from the Arduino. 0 Deg is 90 Deg off to the right. So I know I have to offset it by 180 Deg but am hopeless at math. The sweep would have to start at 270 Deg and sweep through to 0 Deg.
Any help would be appreciated.
Pls don't jump on me. Just trying to learn.
Here is my code. I used a tutorial as a base and kind of guessed my way through.
CODE:
/*
* simple-drawing.c - demonstrate drawing of pixels, lines, arcs, etc.
* on a window. All drawings are done in black color
* over a white background.
*/
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h> /* getenv(), etc. */
#include <unistd.h> /* sleep(), etc. */
#include <math.h>
/*
* function: create_simple_window. Creates a window with a white background
* in the given size.
* input: display, size of the window (in pixels), and location of the window
* (in pixels).
* output: the window's ID.
* notes: window is created with a black border, 2 pixels wide.
* the window is automatically mapped after its creation.
*/
Window
create_simple_window(Display* display, int width, int height, int x, int y)
{
int screen_num = DefaultScreen(display);
int win_border_width = 2;
Window win;
/* create a simple window, as a direct child of the screen's */
/* root window. Use the screen's black and white colors as */
/* the foreground and background colors of the window, */
/* respectively. Place the new window's top-left corner at */
/* the given 'x,y' coordinates. */
win = XCreateSimpleWindow(display, RootWindow(display, screen_num),
x, y, width, height, win_border_width,
BlackPixel(display, screen_num),
WhitePixel(display, screen_num));
/* make the window actually appear on the screen. */
XMapWindow(display, win);
/* flush all pending requests to the X server. */
XFlush(display);
return win;
}
GC
create_gc(Display* display, Window win, int reverse_video)
{
GC gc; /* handle of newly created GC. */
unsigned long valuemask = 0; /* which values in 'values' to */
/* check when creating the GC. */
XGCValues values; /* initial values for the GC. */
unsigned int line_width = 2; /* line width for the GC. */
int line_style = LineSolid; /* style for lines drawing and */
int cap_style = CapButt; /* style of the line's edje and */
int join_style = JoinBevel; /* joined lines. */
int screen_num = DefaultScreen(display);
gc = XCreateGC(display, win, valuemask, &values);
if (gc < 0) {
fprintf(stderr, "XCreateGC: \n");
}
/* allocate foreground and background colors for this GC. */
if (reverse_video) {
XSetForeground(display, gc, WhitePixel(display, screen_num));
XSetBackground(display, gc, BlackPixel(display, screen_num));
}
else {
XSetForeground(display, gc, BlackPixel(display, screen_num));
XSetBackground(display, gc, WhitePixel(display, screen_num));
}
/* define the style of lines that will be drawn using this GC. */
XSetLineAttributes(display, gc,
line_width, line_style, cap_style, join_style);
/* define the fill style for the GC. to be 'solid filling'. */
XSetFillStyle(display, gc, FillSolid);
return gc;
}
void
main(int argc, char* argv[])
{
Display* display; /* pointer to X Display structure. */
int screen_num; /* number of screen to place the window on. */
Window win; /* pointer to the newly created window. */
unsigned int display_width,
display_height; /* height and width of the X display. */
unsigned int width, height; /* height and width for the new window. */
char *display_name = getenv("DISPLAY"); /* address of the X display. */
GC gc; /* GC (graphics context) used for drawing */
/* in our window. */
Colormap screen_colormap; /* color map to use for allocating colors. */
XColor black, white;
/* used for allocation of the given color */
/* map entries. */
Status rc; /* return status of various Xlib functions. */
// Johns stuff
int angle=0;
int x1,x2,y1,y2;
int px,py;
// End
/* open connection with the X server. */
display = XOpenDisplay(display_name);
if (display == NULL) {
fprintf(stderr, "%s: cannot connect to X server '%s'\n",
argv[0], display_name);
exit(1);
}
/* get the geometry of the default screen for our display. */
screen_num = DefaultScreen(display);
display_width = DisplayWidth(display, screen_num);
display_height = DisplayHeight(display, screen_num);
/* make the new window occupy 1/9 of the screen's size. */
width = (display_width / 2);
height = (display_height / 2);
printf("window width - '%d'; height - '%d'\n", width, height);
/* create a simple window, as a direct child of the screen's */
/* root window. Use the screen's white color as the background */
/* color of the window. Place the new window's top-left corner */
/* at the given 'x,y' coordinates. */
win = create_simple_window(display, width, height, 50, 50);
/* allocate a new GC (graphics context) for drawing in the window. */
gc = create_gc(display, win, 0);
XSync(display, False);
/* catch expose events */
XSelectInput(display, win, ExposureMask);
/* wait for the expose event */
XEvent ev;
XNextEvent(display, &ev);
/* get access to the screen's color map. */
screen_colormap = DefaultColormap(display, DefaultScreen(display));
/* allocate the set of colors we will want to use for the drawing. */
rc = XAllocNamedColor(display, screen_colormap, "black", &black, &black);
if (rc == 0) {
fprintf(stderr, "XAllocNamedColor - failed to allocated 'black' color.\n");
exit(1);
}
rc = XAllocNamedColor(display, screen_colormap, "white", &white, &white);
if (rc == 0) {
fprintf(stderr, "XAllocNamedColor - failed to allocated 'white' color.\n");
exit(1);
}
/* draw one pixel near each corner of the window */
XDrawPoint(display, win, gc, 5, 5);
XDrawPoint(display, win, gc, 5, height-5);
XDrawPoint(display, win, gc, width-5, 5);
XDrawPoint(display, win, gc, width-5, height-5);
// Draw line.
x1=width / 2;
y1=height / 2;
px=x1;
py=y1;
while(1){
for(angle=0; angle < 360; angle++)
{
x2=x1 + cos((angle * M_PI) / 180) * 150;
y2=y1 + sin((angle * M_PI) / 180) * 150;
XSetForeground(display, gc, black.pixel);
XDrawLine(display, win, gc, x1, y1, x2, y2);
px=x2;
py=y2;
XFlush(display);
usleep(3500);
XSetForeground(display, gc, white.pixel);
XDrawLine(display, win, gc, x1, y1, px ,py);
XFlush(display);
XSetForeground(display, gc, black.pixel);
usleep(3500);
}
}
// End.
/* flush all pending requests to the X server. */
XFlush(display);
XSync(display, False);
/* make a delay for a short period. */
sleep(4);
/* close the connection to the X server. */
XCloseDisplay(display);
}
Simply trying to draw a moving line without flicker. I understand the concept but am a crap coder.
Any help would be appreciated.
Thanks,
John.``

Frequency Adjusting with STM32 DAC

I used STM32F407VG to create a 30 khz sine wave. Timer settings are; Prescaler = 2-1, ARR = 1, also the clock is 84 Mhz(the clock which runs DAC).
I wrote a function called generate_sin();
#define SINE_ARY_SIZE (360)
const int MAX_SINE_DEGERI = 4095; // max_sine_value
const double BASLANGIC_NOKTASI = 2047.5; //starting point
uint32_t sine_ary[SINE_ARY_SIZE];
void generate_sine(){
for (int i = 0; i < SINE_ARY_SIZE; i++){
double deger = (sin(i*M_PI*360/180/SINE_ARY_SIZE) * BASLANGIC_NOKTASI) + BASLANGIC_NOKTASI; //double value
sine_ary[i] = (uint32_t)deger; // value
}
This is the function which creates sine wave. I used HAL DMA to send DAC output variables.
HAL_TIM_Base_Start(&htim2);
generate_sine();
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, sine_ary, SINE_ARY_SIZE, DAC_ALIGN_12B_R);
These are the codes i used to do what i want. But im having a trouble to change frequency without changing prescaler or ARR.
So here is my question. Can i change frequency without changing timer settings ? For example i want to use buttons and whenever i push button i want my frequency to change.
The generate_sine function will give you one period of a sine wave which has SINE_ARY_SIZE of samples.
To increase the frequency you need to make the period shorter (for 2x frequency, you would have half the number of samples per period). So you should calculate the array for smaller SINE_ARY_SIZE (which will fill just part of the original buffer with a shorter sine wave) and also put this smaller value in the HAL_DAC_Start_DMA function.
Decreasing the frequency will require making the array longer.
You should declare the sine_ary with a maximum length that you will need (for lowest frequency). Make sure it fits in RAM.
#define MAXIMUM_ARRAY_LENGTH 360
uint32_t usedArrayLength = 180;
const double amplitude = 2047.5;
uint32_t sine_ary[MAXIMUM_ARRAY_LENGTH];
void generate_sine(){
for (int i = 0; i < usedArrayLength; i++){
double value = (sin(i*M_PI*2/usedArrayLength) * amplitude) + amplitude;
sine_ary[i] = (uint32_t)value; // value
}
This will have two times higher frequency than the original code, because it only has 180 samples per period, compared to 360.
Start it using
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, sine_ary, usedArrayLength, DAC_ALIGN_12B_R);
To change the frequency, stop DAC, change the value of usedArrayLength (smaller value means higher frequency, must be less or equal to MAXIMUM_ARRAY_LENGTH). Then call the generate_sine function and start the DAC again by the same function (that now uses new usedArrayLength).
Frequency will be: Clock/prescaler/ARR/usedArrayLength
Also, you should use uint16_t for the array (values are from 0 to 4095, the DAC is 12bit I suppose) and DMA should be set to Half-word (2 bytes per value).

How to calibrate internal temperature sensor value in STM32 L496ZGT4

I'm creating simple project using STM32 L946ZGT4. I'd like to use the internal temperature sensor. I configured ADC and i can get value from this. My problem is with calibrate this sensor. Using Reference Manual and Datasheet instructions my final value in celsius degrees equals -17. The ADC value is about 800. Here is my code for sensor calibrating.
#include "Myfun.h"
#include "HD44780.h"
extern uint16_t tab[100];
char buf[16];
float sum, avg;
#define TS_CAL1((uint16_t*)((uint32_t) 0x1FFF75A8))
#define TS_CAL2((uint16_t*)((uint32_t) 0x1FFF75CA))
#define TS_CAL1_TEMP 30.0 f
#define TS_CAL2_TEMP 130.0 f
int32_t temperature;
int main(void)
{
SysTick_Config(4000000 / 1000);
LCD_Init();
Led_Conf();
ADC_Conf_DMA_TempSensor();
while (1)
{
sum = 0;
for (int i = 0; i < 100;)
{
sum = sum + tab[i];
++i;
}
avg = sum / 100; // here is my value from ADC
temperature = (int32_t)(((TS_CAL2_TEMP - TS_CAL1_TEMP) / ((float)(*TS_CAL2) - (float)(*TS_CAL1))) *
(avg - (float)(*TS_CAL1)) + 30.0);
sprintf(buf, "%d C", temperature);
LCD_Clear();
LCD_WriteText(buf);
delay_ms(60);
}
}
you have to convert your ADC reading to volt by:
ADC_value / ADC_maxvalue * ADC_refvoltage
with
ADC_value: the value you get back from the ADC
ADC_maxvalue: 2^12 = 4096, when you are sampling in the 12-bit mode
ADC_revoltage: 3.3 Volt, typically - except you are using a different reference voltage
Then apply the formula from the datasheet, chapter "Electrical Characteristics" --> "Operating Conditions" --> "Temperature Sensor", where you find the offset and the scale (plus the formula) to convert the voltage to temperature ...

How to scale, crop, and rotate all at once in Android RenderScript

Is it possible to take a camera image in Y'UV format and using RenderScript:
Convert it to RGBA
Crop it to a certain region
Rotate it if necessary
Yes! I figured out how and thought I would share it with others. RenderScript has a bit of a learning curve, and more simple examples seem to help.
When cropping, you still need to set up an input and output allocation as well as one for the script itself. It might seem strange at first, but the input and output allocations have to be the same size so if you are cropping you need to set up yet another Allocation to write the cropped output. More on that in a second.
#pragma version(1)
#pragma rs java_package_name(com.autofrog.chrispvision)
#pragma rs_fp_relaxed
/*
* This is mInputAllocation
*/
rs_allocation gInputFrame;
/*
* This is where we write our cropped image
*/
rs_allocation gOutputFrame;
/*
* These dimensions define the crop region that we want
*/
uint32_t xStart, yStart;
uint32_t outputWidth, outputHeight;
uchar4 __attribute__((kernel)) yuv2rgbFrames(uchar4 in, uint32_t x, uint32_t y)
{
uchar Y = rsGetElementAtYuv_uchar_Y(gInputFrame, x, y);
uchar U = rsGetElementAtYuv_uchar_U(gInputFrame, x, y);
uchar V = rsGetElementAtYuv_uchar_V(gInputFrame, x, y);
uchar4 rgba = rsYuvToRGBA_uchar4(Y, U, V);
/* force the alpha channel to opaque - the conversion doesn't seem to do this */
rgba.a = 0xFF;
uint32_t translated_x = x - xStart;
uint32_t translated_y = y - yStart;
uint32_t x_rotated = outputWidth - translated_y;
uint32_t y_rotated = translated_x;
rsSetElementAt_uchar4(gOutputFrame, rgba, x_rotated, y_rotated);
return rgba;
}
To set up the allocations:
private fun createAllocations(rs: RenderScript) {
/*
* The yuvTypeBuilder is for the input from the camera. It has to be the
* same size as the camera (preview) image
*/
val yuvTypeBuilder = Type.Builder(rs, Element.YUV(rs))
yuvTypeBuilder.setX(mImageSize.width)
yuvTypeBuilder.setY(mImageSize.height)
yuvTypeBuilder.setYuvFormat(ImageFormat.YUV_420_888)
mInputAllocation = Allocation.createTyped(
rs, yuvTypeBuilder.create(),
Allocation.USAGE_IO_INPUT or Allocation.USAGE_SCRIPT)
/*
* The RGB type is also the same size as the input image. Other examples write this as
* an int but I don't see a reason why you wouldn't be more explicit about it to make
* the code more readable.
*/
val rgbType = Type.createXY(rs, Element.RGBA_8888(rs), mImageSize.width, mImageSize.height)
mScriptAllocation = Allocation.createTyped(
rs, rgbType,
Allocation.USAGE_SCRIPT)
mOutputAllocation = Allocation.createTyped(
rs, rgbType,
Allocation.USAGE_IO_OUTPUT or Allocation.USAGE_SCRIPT)
/*
* Finally, set up an allocation to which we will write our cropped image. The
* dimensions of this one are (wantx,wanty)
*/
val rgbCroppedType = Type.createXY(rs, Element.RGBA_8888(rs), wantx, wanty)
mOutputAllocationRGB = Allocation.createTyped(
rs, rgbCroppedType,
Allocation.USAGE_SCRIPT)
}
Finally, since you're cropping you need to tell the script what to do before invocation. If the image sizes don't change you can probably optimize this by moving the LaunchOptions and variable settings so they occur just once (rather than every time) but I'm leaving them here for my example to make it clearer.
override fun onBufferAvailable(a: Allocation) {
// Get the new frame into the input allocation
mInputAllocation!!.ioReceive()
// Run processing pass if we should send a frame
val current = System.currentTimeMillis()
if (current - mLastProcessed >= mFrameEveryMs) {
val lo = Script.LaunchOptions()
/*
* These coordinates are the portion of the original image that we want to
* include. Because we're rotating (in this case) x and y are reversed
* (but still offset from the actual center of each dimension)
*/
lo.setX(starty, endy)
lo.setY(startx, endx)
mScriptHandle.set_xStart(lo.xStart.toLong())
mScriptHandle.set_yStart(lo.yStart.toLong())
mScriptHandle.set_outputWidth(wantx.toLong())
mScriptHandle.set_outputHeight(wanty.toLong())
mScriptHandle.forEach_yuv2rgbFrames(mScriptAllocation, mOutputAllocation, lo)
val output = Bitmap.createBitmap(
wantx, wanty,
Bitmap.Config.ARGB_8888
)
mOutputAllocationRGB!!.copyTo(output)
/* Do something with the resulting bitmap */
listener?.invoke(output)
mLastProcessed = current
}
}
All this might seem like a bit much but it's very fast - way faster than doing the rotation on the java/kotlin side, and thanks to RenderScript's ability to run the kernel function over a subset of the image it's less overhead than creating a bitmap then creating a second, cropped one.
For me, all the rotation is necessary because the image seen by the RenderScript was 90 degrees rotated from the camera. I am told this is some kind of peculiarity of having a Samsung phone.
RenderScript was intimidating at first but once you get used to what it's doing it's not so bad. I hope this is helpful to someone.

Transmitting data from Arduino UNO into MATLAB but getting a lot of NaNs and numbers with missing digits

I'm collecting degree data from an encoder using an Arduino Uno, and then sending that data into MATLAB using USB. In order to get velocity of rotation as well, I'm generating and sending a timestamp after every degree data point from the Arduino into MATLAB. The data is generated flawlessly on the Arduino side--there's nothing wrong on the Serial Monitor.
In MATLAB, however, my data matrices fill up with quite a few NaNs, as well as the occasional integer with a missing first digit. For example, instead of 216 degree, I get 16 degrees coming through, or instead of 7265900 microseconds, I get 265900 microseconds coming through.
I've been able to solve the issue of losing time data by using Arduino's millis() clock instead of its micros() clock and by adding a 50 millisecond delay after the encoder reading. The problem of degree data loss goes away if I increase the delay after the millis() clock, but then degree data acquisition becomes too slow to be useful.
Any help would be much appreciated!
Code pasted below. First the Arduino code, then the MATLAB code.
Thank you!
David
#include <Adafruit_LEDBackpack.h>
#include <Adafruit_GFX.h>
#include <gfxfont.h>
#include <SPI.h> //Include the SPI library in this sketch.
#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
//#include <TinyWireM.h> // Enable this line if using Adafruit Trinket, Gemma, etc.
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
Adafruit_7segment matrix = Adafruit_7segment();
//Variables for SPI rotary encoder
boolean knob_detected = false;
byte slave_select = 10; //Slave select pin.
byte mosi = 11; //MOSI pin.
byte miso = 12; //MISO pin.
byte spi_clock = 13; //Clock pin.
byte read_counter = 96;
byte write_mode0 = 137;
byte write_mode1 = 144;
byte count1;
byte count2;
int count;
int val;
int button = 7;
int b = 0;
int degree;
int absolute;
unsigned long time;
// SETUP //
void setup() {
//Connect the 4 communication pins between the Arduino and the quadrature counter.
#ifndef __AVR_ATtiny85__
Serial.begin(9600);
//Serial.println("7 Segment Backpack Test");
#endif
matrix.begin(0x70);
pinMode(slave_select, OUTPUT);
pinMode(mosi, OUTPUT);
pinMode(miso, INPUT);
pinMode(spi_clock, OUTPUT);
// pinMode(button,INPUT);
SPI.begin(); //Begin SPI communication.
SPI.setBitOrder(MSBFIRST); //Bytes read into SPI will be read in MSB style.
SPI.setDataMode(SPI_MODE0); //Set the data to shift on the low clock phase with normal (non-inverted) clock polarity.
digitalWrite(slave_select, HIGH); //Close the SPI communication port.
SPI.setClockDivider(SPI_CLOCK_DIV128); //Set the SPI clock to 125 kHz (This can be changed).
digitalWrite(slave_select, LOW); //Set slave select low to enable communication.
SPI.transfer(write_mode0); //Select mode 0 for modifying.
SPI.transfer(0b01000011); //Write to mode 0: Synchronous Index, disable index, range-limit count mode, x4 quadrature.
digitalWrite(slave_select, HIGH); //Set slave select high to disable communication
digitalWrite(slave_select, LOW); //Set slave select low to enable communication
SPI.transfer(write_mode1); //Select mode 1 for modifying.
SPI.transfer(2); //Write across a 0b01 to mode1 to enable 2 byte data transfers
digitalWrite(slave_select, HIGH); //Set slave select high to disable communication
Serial.begin(9600); //Set the baud rate for serial data transmission.
//Serial.println("READY"); //Print "READY" to the serial line to indicate that initialization is complete.
}
// MAIN LOOP //
void loop() {
digitalWrite(slave_select, LOW); //Set slave_select pin low to begin tranmission .
SPI.transfer(read_counter); //Read from the read_counter register.
count1 = SPI.transfer(0); //Send a null transfer to read byte1 values.
count2 = SPI.transfer(0); //Send a null transfer to read byte2 values.
digitalWrite(slave_select, HIGH); //Set slave_select high to end transmission.
count = word(count1, count2); //Type cast the 2 bytes as a word.
degree = count / 4;
absolute = abs(degree);
//Send back the value of the register over the serial line.
b = digitalRead(button);
if (b == HIGH) {
digitalWrite(absolute,LOW);
}
else {}
if (absolute == LOW)
{
absolute = 0;
}
else {}
Serial.println(absolute); //Send back the value of the register over the serial line.
matrix.print(absolute,DEC);
matrix.writeDisplay();
delay(50); //Pause for 50 milliseconds before re-looping.
time = millis();
Serial.println(time);
delay(10);
}
clear all;
close all;
clc;
delete(instrfind); %delete connected ports
p=getserialport;
[m,n] = listdlg('PromptString','Select Your Bluetooth device:','SelectionMode','single','ListString',p);
com=cell2mat(p(m));
s=serial(com);
fopen(s);
csd = figure;
set(csd,'Name','Plotting Arduino Data on MATLAB','NumberTitle','off'); % open Figure
t=1:100;% total Figure
hAx(1) = subplot(211);
hLine(1) = line('XData',t, 'YData',nan(size(t)), 'Color','b', 'Parent',hAx(1));
xlabel('Samples'), ylabel('Degrees');
hAx(2) = subplot(212);
hLine(2) = line('XData',t, 'YData',nan(size(t)), 'Color','b', 'Parent',hAx(2));
xlabel('Samples'), ylabel('Velocity');
set(hAx, 'Box','on', 'YGrid','on');
axis(hAx(1),[0,100,0,100]);
axis(hAx(2),[0,100,0,100000]);
d=zeros(1,100); %buffer of 100 elements
sm=zeros(1,10); %buffer of 10 elements
t10=zeros(1,10); %buffer of 10 elements
t100=zeros(1,100); %buffer of 100 elements
while(1)
j=1;
while(j<=10)
flushinput(s);
sc=(fscanf(s));
if(length(sc)<6) %1000 degree units = 6 char (was <7 for micros() clock)
sm(j)=str2double(sc);
else %i.e. else, if a timestamp (more than 7 chars)
t10(j)=str2double(sc);
j=j+1;
end
end
t100 = [t100,t10];
t100 = t100(11:end);
d=[d,sm]; %Add new Samples
d=d(11:end); %Remove old Samples
%d(end)
set(hLine(1), 'YData',d); %draw Degrees
set(hLine(2), 'YData',t100); %draw Velocity (currently just timestamps)
drawnow %# force MATLAB to flush any queued displays
end
(getserialport function defined by the following m-file)
function x=getserialport
serialInfo = instrhwinfo('serial');
x=serialInfo.SerialPorts;
end