Scope with PIC microcontroller and Matlab

June 23, 2008 at 3:30 pm 42 comments

After many trials I recently succeeded in using the serial connection for communication between my PIC experimental board (based on a PIC18F4455) and my laptop. Turned out I was configuring my UART wrong, but now it works. I’m very happy about this because it is very useful for debugging my robot controller. I wrote a script in Matlab to read out the sensorvalues from the COM port and plot them in some sort of scope-window. The result looks pretty cool!

You can download the code by clicking on the links at the bottom of this post. You must add pclink.c and pclink.h to your PIC project. Before using the functions in this file you should initialize the USART, e.g. with this code:

void USART_Init() { 

 

TRISCbits.TRISC7=1; // RX 
TRISCbits.TRISC6=0; // TX 
SPBRG = 0x71; 
SPBRGH = 0x02; // 0x0271 for 48MHz -> 19200 baud 
TXSTA = 0x24; // TX enable BRGH=1 
RCSTA = 0x90; // continuous RX 
BAUDCON = 0x08; // BRG16 = 1 
} 

 

In Matlab you have to start the sensorPlot script. This will ask for the sensorvalues and wait for the response every timestep. These values are shown in a plot.  

 

Matlab scope (from PIC ADC input)

Matlab scope (from PIC ADC input)

 

 

Advertisements

Entry filed under: Uncategorized. Tags: , , , , , , , .

Switch from ASP to PHP Google Earth Cacher

42 Comments Add your own

  • 1. Dan  |  November 28, 2008 at 9:56 pm

    Hi there, I am trying to do exactly the same thing, interfacing my pic with matlab. The difference is that i want to send information to the pic18f4431 into PORTA and make a combination of LEDS light up from matlab…

    The PIC code in PICC18 compiler in MPLAB is below:

    #include
    #include

    void main(void)
    {
    ANSEL0=0b00000000;

    TRISA = 0b00000000;
    RCSTA=0b10010000;
    TXSTA=0b00100000;
    SPBRG=0x0F;

    wait:
    if(PIR1bits.RCIF==0)
    {
    goto wait;
    }

    PORTA=RCREG;
    }

    I was hoping this would program the pic to receive data serially…

    The matlab code is below:

    b=[7 4];
    s = serial(‘COM2′);
    set(s,’BaudRate’,9600,’DataBits’,8,’Parity’,’none’ ,’StopBits’,1,’FlowControl’,’none’,’InputBufferSiz e’,102400)
    fopen(s);
    s.Status

    if strcmp(s.TransferStatus, ‘idle’) || strcmp(s.TransferStatus,’read’)
    fwrite(s,b,’uint8′,’async’);

    else

    end

    stopasync(s)
    fclose(s)
    delete(s)
    clear s
    display(‘finished’)

    Please could you tell me what im doing wrong or correct my code.

    Thanks

    Reply
  • 2. kr3l  |  November 28, 2008 at 10:15 pm

    Dan,

    Is it possible to add some comments to the code of the main() function, so I know why you chose the values. Is the analog input on port A on your PIC? And where do you want to send the received value (on what port are your leds)?

    Reply
  • 3. Dan  |  November 30, 2008 at 6:51 am

    Hey man

    Thanks, here is the commented code. My serial data is received into PORTC and my LEDS are attached to PORTA.

    #include
    #include
    //My serial PORT is connected to PORTC bits 6 and 7 for RX and TX.

    void main(void)
    {
    //My inputs are therefore on PORTC
    ANSEL0=0b00000000; //Making PORTA digital outputs

    TRISA = 0b00000000;//Making PORTA an output, LEDS are connected to PORTA
    RCSTA=0b10010000;//Making the serial connection continuous receive
    TXSTA=0b00100000;
    SPBRG=0×0F; //Setting BAUD rate to 9600

    wait:
    if(PIR1bits.RCIF==0)
    {
    goto wait;
    }

    PORTA=RCREG; //Loading PORTA with values received from matlab
    }

    Thanks

    Reply
  • 4. Dan  |  November 30, 2008 at 7:04 am

    By the way, PORTA has the possibility of having Analog inputs if you want

    Reply
  • 5. kr3l  |  November 30, 2008 at 5:37 pm

    Dan,

    I don’t know what the error could be, but I do have some suggestions that you could try.

    1/ Perhaps you should read in the values inside a loop, like below. This way, the configuration isn’t executed over and over again.

    while (1) {
    while (!PIR1bits.RCIF); //wait
    PORTA=RCREG; //Loading PORTA with values received from matlab
    }

    2/ I suggest using the USART library functions from Microchip. Below is an extract of my code that could be useful for your purpose:

    #include <usart.h> // include the usart-module, (header is in MCC18/h folder)

    void USART_Init() { //call this from your main, before the loop
    TRISCbits.TRISC7=1; // RX
    TRISCbits.TRISC6=0; // TX
    SPBRG = 0x71;
    SPBRGH = 0x02; // 0x0271 for 48MHz -> 19200 baud
    TXSTA = 0x24; // TX enable BRGH=1
    RCSTA = 0x90; // continuous RX
    BAUDCON = 0x08; // BRG16 = 1
    }

    void main(void) {
    USART_Init();
    TRISA = 0;

    while (1) {
    if (DataRdyUSART( )) {
    PORTA = getcUSART();
    }
    }
    }

    regards,
    Karel

    Reply
  • 6. Dan  |  December 1, 2008 at 7:21 am

    Hey Karel,
    I finally got it to work! Thank you so very much for your help! I actually used your initialisation routine and took out the Baud control options and it worked perfectly!
    Just a question, some people were requesting the code, would you mind if I give it to them? If so, would you like me to reference your section?

    Regards

    Dan

    Reply
  • 7. Dan  |  December 1, 2008 at 7:22 am

    By the way, if I want to read data from the PIC, must I change anything to the initialsation routine?

    Thanks 🙂

    Reply
  • 8. kr3l  |  December 1, 2008 at 8:09 am

    Hey Dan,

    Great that you got it to work! Feel free to reuse the code, it would be nice if you reference people back to this site.

    The initialization remains the same for receiving data.

    Regards,
    Karel

    Reply
  • 9. Dan  |  December 1, 2008 at 1:48 pm

    Hey Karel, Sorry to keep worrying you but I have hit another snag.
    Ive been trying to read information into matlab. When i send a letter or a number for example and i load it into my bootloader to load onto the pic, the number gets loaded infinitely into matlabs input buffer memory and fills up the memory.

    The code is below:

    If you can see any problems please would you help me again? Thanks, this part of the project is make my hair grey slowly…..

    #include
    #include
    #include
    //START HERE

    //END HERE

    void delay()
    {

    for (int j=0;j0)
    out=fread(s,s.BytesAvailable,’uint8′);
    display(out)
    end

    stopasync(s)
    %out = fscanf(s);
    fclose(s)
    delete(s)
    clear s
    display(‘finished’);

    Thanks so much again if you can or cant help

    Regards

    Dan

    Reply
  • 10. Dan  |  December 2, 2008 at 4:41 pm

    Sorry I dont think the code came out well, do you have an email i can send the code to or do you know of some way to initialise my pic and matlab so that matlab can read data sent from the PIC.

    Thanks again

    Dan

    Reply
  • 11. kr3l  |  December 2, 2008 at 8:39 pm

    Dan,

    This code works for me:


    s2 = serial('COM2','BaudRate',19200);
    fopen(s2);
    s2.ReadAsyncMode = 'continuous';
    while (~s2.BytesAvailable)
    %wait...
    end
    res = fscanf(s2);

    Karel

    Reply
  • 12. Dan  |  December 3, 2008 at 10:15 am

    Thanks very much Karel
    Sorry, Last question, how would you write a pic program in C to send the letter ‘G’ to matlab at 9600 bps? I have tried and tried and tried and matlab does not want to receive the letter even with your code… I think my PIC program is the problem….

    Thanks very much

    Dan

    PS my pic code is below, dunno if it helps:

    #include
    #include
    #include

    void delay()
    {

    for (int j=0;j<30000;j++)
    {
    }

    }

    void main(void)
    {

    TXSTA =0x24; // TX enable BRGH=1
    TRISC=0b10000000; // RX

    RCSTA=0x90; // continuous RX

    delay();

    TXREG = ‘P’;

    while(1)
    {
    wait:
    if(TXIF==0)
    {
    goto wait;
    }
    }

    }//END MAIN

    Reply
  • 13. kr3l  |  December 6, 2008 at 10:30 pm

    Dan,

    Have you tried using the stdio functions?

    fprintf (_H_USART, "G");

    should print the G character (no code required to wait for it to be sent). You’ll have to include stdio.h (and perhaps stdlib.h also) into your code to use this.

    Reply
  • 14. Dan  |  December 7, 2008 at 10:08 am

    dont think I have this function in my library as when i put code like this into my program, I get the following error:

    Warning [361] C:\Documents and Settings\Dan\Desktop\Stagerim\Technion Work\ReadPIC\ReadMain.c; 38.1 function declared implicit int
    Error [192] C:\Documents and Settings\Dan\Desktop\Stagerim\Technion Work\ReadPIC\ReadMain.c; 38.10 undefined identifier “_H_USART”

    ********** Build failed! **********

    Is there a way to get it into my Hi-Tech c18 library?

    Reply
  • 15. kr3l  |  December 7, 2008 at 2:01 pm

    Ah, you’re using Hi-Tech compiler, I didn’t know that. I don’t have experience with it, but I would look into you usart.h header file and look for a function that writes a character to the usart. In my library it is called putc1USART or Write1USART, I guess the name in your library should be about the same.

    Reply
  • 16. Dan  |  December 9, 2008 at 8:55 am

    Karl, Thanks so much for your help, I hope I didnt bother you too much! 🙂

    Thanks again

    Dan

    Reply
  • 17. kr3l  |  December 9, 2008 at 9:00 am

    no problem 🙂

    Reply
  • 18. srinusingh  |  January 20, 2009 at 10:22 am

    hi
    iam doing the same thing but i have to send 10 bit data from my PIC18 to matlab , how i can do this using serial communicatio

    Reply
  • 19. srinusingh  |  January 20, 2009 at 10:24 am

    please send me the code for 10 bit data communication between PIC18 and MATLAB

    my email: srinu.singh@gmail.com

    Reply
  • 20. Karel  |  January 20, 2009 at 10:31 am

    I don’t have any experience with this, but an easy shortcut could be to send 2 characters (8 bits) and combine them to a 16 bit value in Matlab (so wait for two received chars in Matlab).

    I don’t know if there is a better solution. My first guess would be that you are stuck with sending 8 bit values because of the 8bit registers used in the UART, but perhaps I am missing something.

    Reply
  • 21. srinusingh  |  January 24, 2009 at 10:05 am

    please help me……..
    hi …..iam doing analog to digital conversion using PIC18f452.
    Now i have to send digital output to PC using RS232.My problem is PIC18 ADC is 10 bit , but data transmit register is only 8bit , how i can send this 10bit output to PC using RS232 interface.

    Reply
  • 22. srinusingh  |  January 24, 2009 at 10:07 am

    please anybody send me code for this
    my email: srinu.singh@gmail.com

    Reply
  • 23. srinusingh  |  January 24, 2009 at 10:10 am

    NOTE: In the above discussion iam doing analog to digital conversion of continuous real time data.

    Reply
  • 24. Karel  |  January 24, 2009 at 12:23 pm

    have you tried my suggestion? Split up the 10-bit in two 8-bit values, where the first 8bit variable contains the first 8 bits from your 10 bit value, and the second 8bit variable contains the last 2 bits (and some zeros). In Matlab you can combine these two 8 bit variables again into a 10 bit variable.

    Reply
  • 25. srinusingh  |  January 24, 2009 at 4:10 pm

    Thank u very much ……
    I trying like this as u said , regarding PIC programming i don’t have any problem. But in MATLAB i don’t know exactly which operator is used to combine these two 8bit values to form a 10bit value(or 16 bit value) in MATLAB.

    Please help me…….

    Reply
  • 26. srinusingh  |  January 27, 2009 at 4:54 am

    Hi Karel
    Please help me on MATLAB .
    please send me the code to form 16 bit data using two 8bit values, and i have to display the signal using these values in MATLAB.
    How i can do this .
    Please help me……….please…….

    Reply
  • 27. Karel  |  January 27, 2009 at 8:17 am

    Hey srinusingh,

    My Matlab crashed this weekend so I’m not able to test code. If you have two values A and B of 8 bit that you want to combine into C (16 bit) than I guess it is just
    C=A*256+B;
    Because 2^8=256 will shift A 8 positions. If only the least two bits of A are used (so A is 000000xx in binary) than you have your 10 bit value in Matlab!

    Reply
  • 28. srinusingh  |  January 27, 2009 at 9:35 am

    Thank you very much Karel………
    i keep me in touch with you
    Thanks

    Reply
  • 29. srinusingh  |  January 31, 2009 at 4:14 pm

    Hi Karel .
    I tried to form a 16 bit data using two 8bit datas in MATLAB.
    I tried to receive two 8 bit data bytes seperatelyin MATLAB, but i used the same command to receive both data bytes .Actually i have to receive these two data bytes seperately to form a 16 bit data.
    can u please give the code for this.

    Reply
  • 30. Karel  |  January 31, 2009 at 4:40 pm

    How do you mean “seperately”? If you mean receive them in parallel it is impossible. If you mean one after the other, you have to assign them to different variables in Matlab. What is you Matlab code?

    Reply
  • 31. srinusingh  |  February 1, 2009 at 8:45 am

    Hi Karel
    seperately means not in parllel, I don’t have much idea in matlab.
    I have the doubt that ,weather i receive the continuous data bytes (MSB and LSB bytes)in matlab and can i able to add them.
    I wrote like this in matlab

    data1=serial(‘COM1′);
    set(data1,’Baudrate’,9600,’Databits’,8,’parity’,’none’,’Flowcontrol’,’none,)
    fopen(data1);
    MSB=fscanf(data1);
    data2=serial(‘COM1′);
    set(data2,’Baudrate’,9600,’Databits’,8,’parity’,’none’,’Flowcontrol’,’none,)
    fopen(data2);
    LSB=fscanf(data2);
    DATA=MSB*256+LSB;
    fclose(data1)
    delete(data1)
    clear data1
    fclose(data2)
    delete(data2)
    clear data2

    I tried this in matlab but iam not getting what iam expecting .
    This code correct or not i don’t know because i don’t have much idea in matlab.
    If this is wrong can u give me the correct code .
    And finally i have to display the DATA in matlab in analog form.
    please help me , since iam receiving ADC output in MATLAB.
    so, i have to display the original analog data in matlab.
    My mail is : ***

    Reply
  • 32. nitlogic  |  March 30, 2009 at 7:37 am

    where can I read about microcontroller in your blog?! I have searched about the word “atmel microcontroller” and you blog appeared to me

    Reply
  • 33. Karel  |  March 30, 2009 at 8:00 am

    Hi nitlogic,

    I only talk about the PIC microcontroller in my blog. Use the tagcloud and click on PIC if you are still interested

    Reply
  • […] Reading in sensor values and sending them to Matlab […]

    Reply
  • 35. Sergei  |  February 9, 2010 at 8:22 pm

    I’m a student, last year, and my course prodject is similar to your PIC-prodject. Do you can send me to look only Matlab code!

    Reply
  • 36. Karel  |  February 10, 2010 at 8:56 am

    Sergei, the Matlab code is available here: http://trol.freehostia.com/Files/art182_23-6-2008_402_commun.m

    Reply
  • 37. Diego  |  March 17, 2010 at 4:52 pm

    Nice work… Very useful.

    Reply
  • 38. PICman  |  March 29, 2010 at 8:57 am

    Hi,

    I’m trying to do something very similar to what Dan was doing up above. I’m using a PIC18F4520 microcontroller with realterm terminal software to read data. I have no trouble sending data from the PIC to realterm, but now I want to send data from the terminal to the PIC and read the same data back on screen. I’m pretty sure this isn’t impossible (:P) but i cant seem to pull it off. My code for this is shown below –

    while(1)
    {

    while(PIR1bits.RCIF == 1); //RCREG is full
    receivedata = RCREG; //Load RCREG

    TXREG= receivedata; //Load TXREG
    while(!TXSTAbits.TRMT); //Wait until TSR is empty

    }

    i suspect the problem lies somewhere along the lines of not being able to use RCREG and TXREG simultaneously.

    My USART is initialized as follows –
    TXSTA = 0b00100000;
    RCSTA = 0b10010000;

    I’m using a baud rate of 1200 (ridiculously slow but required). If theres anything I missed please let me know. Any help would be greatly appreciated!!

    thanks

    Reply
  • 39. zohaib  |  June 4, 2010 at 5:46 am

    Sir can u send me the code…because i am not getting it from your page…sir kindly send me ur matlab file code and relative info on my email address zaby2k2@hotmail.com..thankx

    Reply
  • 40. dspic users  |  November 4, 2010 at 1:19 pm

    Hi
    I use a program pretending to read and write on a dsPIC, can you explain the role of both function defined in your Matlab code

    Thank you

    Reply
  • 41. Jofre  |  February 5, 2011 at 5:22 am

    Hi Karel,

    Congratulations I like this serial plotter !
    The links of the source code are not working. Can you tell if there is a new link ?

    Thanks in advance,

    Jofre

    Reply
  • 42. fabian  |  November 27, 2013 at 5:49 am

    disculpa no puedo ver donde descargar el codigo. gracias

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Trackback this post  |  Subscribe to the comments via RSS Feed


Feeds

Articles to be written…

Twitter – kr3l

my del.icio.us

RSS Google Reader Shared Stuff

  • An error has occurred; the feed is probably down. Try again later.

RSS Listening to..

  • An error has occurred; the feed is probably down. Try again later.

%d bloggers like this: