Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Mobile robot using dsPIC30F4011

Status
Not open for further replies.

gabosssss

Newbie level 5
Joined
Jun 20, 2011
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,406
Hello, I'm new here and I want to tell you I'm glad I found this forum. At first view, there are many people here able to help guys with problems (like me :) )
So my problem is this: I have to move a robot, for the begining, using PWM from dsPIC30F4011. I did a program in MPLAB C30, my board is working, my servo motors are moving and I managed to move the wheels when I send something from PC on UART (and stop them when I send again).
I a blocked now, for some hours, because I want to modify this program so when I send "w", "a", "s", "d" from PC, the wheels move "forward", "turn left", "backward", "turn right" (something like PC games). I hope you all understood my problem. My english is not the best. Ask me any details, I'll answer as fast as I can. Thanks in advance!
This is my program so far:

#include "p30f4011.h"

_FOSC(CSW_FSCM_OFF & XT); // Disable clock monitor, external 8MHz oscillator
_FWDT(WDT_OFF); // Disable Watch-Dog Timer.
_FBORPOR(PBOR_OFF & MCLR_EN & PWRT_OFF & PWMxH_ACT_HI); // Brown out reset disabled, enable MCLR reset pin, turn off power-up timer, PWMxH acts high
_FGS(CODE_PROT_OFF); // Disable Code Protection

#define FOSC 8000000 // 8Mhz
#define FCY (FOSC / 4) // 1 inscruction cycle = 4 clock cycles
#define q 8000000

int i,j;
void initserial(double baudr);
void initPWM();

int main(void)
{
int f1;
initserial(9600);
Init_PWM(); // Initialize PWM module

while(1) // Loop forever
{
while(!U1STAbits.URXDA){}
f1=U1RXREG;U1TXREG=f1;

PDC1 = 2000; //forward
PDC2 = 1000; //forward (the servos are positioned somehow mirrored)

while(!U1STAbits.URXDA){}
f1=U1RXREG;U1TXREG=f1;
PDC1 = 1515; //center value for first servo
PDC2 = 1520; //center value for second servo

}//while
}//main

void initserial(double baudr)
{
U1MODE=0;//-- set up the UART
U1STA=0;//-- set up the UART
U1MODEbits.ALTIO=1;
U1BRG=(int)((q-16*baudr)/(16*baudr));
U1MODEbits.UARTEN=1;//--enable the UART
U1STAbits.UTXEN=1;//--enable transmision
}

void Init_PWM(void)
{
PTCONbits.PTEN = 0; // Timer Enable bit: DISABLE MCPWM
PWMCON1bits.PEN1H = 1; // PWM1H (pin 37) is enabled for PWM output
PWMCON1bits.PEN2H = 1; // PWM2H (pin 35) is enabled for PWM output
PTCONbits.PTCKPS = 1;// Input Clock Prescale bits: 1:4
PTCONbits.PTOPS = 0; // Output Clock Postscale bits: 1:1
PTCONbits.PTSIDL = 1; // Stop in Idle Mode: YES
PTCONbits.PTMOD = 0; // Mode Select bits: Free Running Mode
PTCONbits.PTEN = 1; // Timer Enable bit: ENABLE MCPWM
PTPERbits.PTPER = 11250; // Period Value bits
}
 

could you do something along the lines of
Code:
while(1)
  {
  while(!U1STAbits.URXDA){}
  switch(f1=U1RXREG)
    {
     case 'w':    ...   // commands to move forward
                 break;
     case 'a':    ...   // commands to move fleft
                 break;
     case 's':    ...   // commands to move backwards
                 break;
     case 'd':    ...   // commands to move right
                 break;
    }
}
 
That seems to be exactly what I need! I will test it tomorrow morning, because I'm working in a college lab. I have there all I need, the power sources (one for the board and one for the servo motors) and the ICD2 programmator, things I don't own and can't take home. Thank you very much! I'll post here after the test!
Thank you again!

Edit: I made it working. I had some problems with the bits sent on UART (something from the serial initialisation, parity, stop bits). When I was sending for example "0" (zero), the dspic was sending back 1000.0000b, 80H. It took me some time to resolve this, but now it's all good. Thank you very much for helping me! For now I will wait for other requirements from my teacher.
Have a nice day!
 
Last edited:

I got the next requirement from my teacher. He says I should make the ADC module working, to acquire data from some infrared sensors..
I will read de datasheet carefull and come back with a (some) question(s). In the meantime, if someone has an advice or something for me, I will gladly take it.
Good night everyone!
 

how many sensors? how often?
have a look at the application notes and the section on the ADC in the data sheet
dsPIC30F4011

and the code examples
**broken link removed**
 

how many sensors? how often?
I honnestly don't have any idea. I will ask him for some details and for the sensor board for tests and will take a look at the links you gave me. Thanks! I'll reply when I'll be able to understand how these things should work.
 

I honnestly don't have any idea. I will ask him for some details and for the sensor board for tests and will take a look at the links you gave me. Thanks! I'll reply when I'll be able to understand how these things should work.

So I got some info: I will use Vishay sensors, TCRT5000. I have to make 3 or 4 different little boards to attach to my robot, because I don't have any more space on my dsPIC board.I think I will put one in front, one in the back, and two on the sides (let's say positioned aprox 45 degree from the front one, to the left and to the right). Ok, so I think I could use the initialisation from "CE002 Configuring 10-Bit dsPIC DSC A/D Converters for 1 Msps Conversion Rate" code example, but I don't really know how to call that function in my main program. I mean, something like when an obstacle is detected, some register (or a bit from a register) announce and make the robot move another way. :-?
 

here is a simple program reading an ADC using polled IO for a dsPIC30F3011
Code:
// program to poll ADC
// on EASYdsPIC2 board is pot on top right hand corner - instal jumper!

#include "targetBoard.h"

// SET UP CONFIGURATION REGISTER
 _FOSC(CSW_FSCM_OFF & XT_PLL4); 	// primary oscillator 4xPLL
 _FWDT(WDT_OFF); 					// Turn off Watchdog Timer


#include <timer.h>
#include "lcd.h"


// initialise ADC0 to read data
void adc0initialise()
{  					      
  TRISBbits.TRISB0=1;
  ADPCFG = 0xFFFE;                    //   all PORTB = Digital; RB2 = analog
  ADCON1 = 0x0000;                    //   SAMP bit = 0 ends sampling ...
                                      //   and starts converting
  ADCHS    = 0x0000;                  //   Connect RB0/AN0 as CH0 input ..
                                      //   in this example RB2/AN2 is the input
  ADCSSL = 0;
  ADCON3 = 0x0002;                    // Manual Sample, Tad = internal 2 Tcy
  ADCON2 = 0;
  //ADCON1=0x100;
  ADCON1bits.ADON = 1;                // turn ADC ON
}  

// read adata from ADC0
int adc0read()
{
       ADCON1bits.SAMP = 1;            //   start sampling ...
       DelayNmSec(1);                  //   delay
       ADCON1bits.SAMP = 0;            //   start Converting
       while (!ADCON1bits.DONE);       //   conversion done?
       return ADCBUF0;                 //   yes then get ADC value
}

                  
int  main(void)
  {  
  int i;
  initUART(57600L);//115200L);						  // initialise UART
  adc0initialise();
  puts("\n\r\n\rADC test\n\r");
 // lcd_init();
//  lcd_string_at_cursor("ADC test");
  while (1)                                // repeat continuously
   {
    i=adc0read();
    
   }                                               
 }
 

I made three little boards with the TCRT5000 sensors, verified them using an oscilloscope, all good, but I have one question: can I make the adc0initialise for all three of them? Or I must write an initialisation for each of my sensor (for each channel)? I'd like to use for example AN0, AN1 and AN2 to read data from sensors. And after this, in the while loop, can I use variable "i" for all three? Or a different variable for each sensor?
I'm sorry if you find this easy, but I'm new in microcontroller programming. Thanks again!

EDIT: In the example you have been provided me for the ADC, i get an error at delayNmsec(1). I included timer.h, but I get the same error. Then I replaced with a "for", but still don't get nothing from the sensor. I don't know what to do next..
 
Last edited:

Can't figure it out. This ADC thing. I tried all kind of initialisation. Auto-sample, start sample when SAMP bit is enable, tried changing other bits in all the registers, but after 12 hours of work, still nothing. I need to configure it for three infrared sensors. Sometimes I get some numbers back on U1TXREG, but nothing good. I would like to configure RB0, RB1 and RB2 as inputs for the sensor's signals. Please help. I have only 6 days before I must have it finished, and didn't start the theory (written) part!
 

Hello again. I managed to configure ADC for one channel (CH0). I need three working channels. CH0 is on RB0/AN0 and I don't know how to enable CH1 and CH2 on RB1/AN1 and RB2/AN2 (or other, doesn't matter). I tried using different initialisations for each channel, but couldn't read them. Hope you could help me, please. My code for ADC is next (I let my tryings commented to see what didn't work for me):

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#include "p30f4011.h" 
 
#define FOSC 8000000  // 8Mhz
#define FCY (FOSC / 4) // 1 inscruction cycle = 4 clock cycles
#define MILLISEC FCY/8000
#define q 8000000
#define BAUD_RATE 9600 // Slower baud rate chosen
#define UXBRG (((FCY / 16) / BAUD_RATE) -1)
 
/****************************************************
* Function: int main(void)                          *
* Purpose: program entry point                      *
* Description: This is where the main loop resides. *
****************************************************/
 
unsigned int i,j,k;
void initserial(double baudr);
void Init_PWM(void);
void adc0initialise();
void DelayNmSec(unsigned int N);
 
int main(void)
{
    unsigned int f1;
    initserial(9600);
    Init_PWM();   // Initialize PWM module  
    adc0initialise();
    //adc1initialise();
    //adc2initialise();
    
    PDC1 = 2000;
    PDC2 = 1000;
 
    while(1) // Loop forever
    {
        
        i=adc0read();
        i = i >> 2;
        DelayNmSec(200);
        U1TXREG=i;
        if(i>200)   
            {
                PDC1 = 1500;
                PDC2 = 1500;
 
            }
        else
    {
        PDC1 = 2000;
        PDC2 = 1000;
    }
 
//          while(!U1STAbits.URXDA){}
//          f1=U1RXREG;U1TXREG=f1;
//                  switch(f1)
//                  {
//                  case 'w':   
//                          PDC1 = 2000; 
//                          PDC2 = 1000;    // commands to move forward
//                  break;
//          
//                  case 'a': 
//                              PDC1 = 2000; 
//                          PDC2 = 1520;    // commands to move left
//                  break;
//      
//                  case 's':   
//                          PDC1 = 1000; 
//                          PDC2 = 2000;    // commands to move backwards
//                  break;
//      
//                  case 'd':
//                          PDC1 = 1515; 
//                          PDC2 = 1000;    // commands to move right
//                  break;
//
//                  case 'x':
//                          PDC1 = 1515;
//                          PDC2 = 1520;    //stop
//              }
//      for  (i=0;i<1000;i++)
//          for (j=0;j<500;j++)
//{
//          PDC1 = 2000; // This sets the duty cycle, for or servo (or motor) 1875 is neutral.
//          PDC2 = 1000;
//
//      while(!U1STAbits.URXDA){}//--asteapta un octet== identificator    
//                  f1=U1RXREG;U1TXREG=f1;
//          PDC1 = 1515; // This sets the duty cycle, for or servo (or motor) 1875 is neutral.
//          PDC2 = 1520;
//}
//      for (i=0;i<1000;i++)
//          for (j=0;j<500;j++)
//{
//  PDC1 = 1515;
//  PDC2 = 1520;
//}
    }//while
}//main 
 
void initserial(double baudr)
 {
    U1BRG = UXBRG; // Set the baud rate
    U1MODEbits.PDSEL = 0; // 8 data bits, no parity
    U1MODEbits.STSEL = 0; // 1 stop bit 
    U1MODEbits.LPBACK = 0; // Disable LoopBack mode
    U1MODEbits.ALTIO  = 1; // Use alternate UART TX & RX
    U1MODEbits.UARTEN = 1; // Enable UART module
    U1STAbits.UTXBRK = 0;
    U1STAbits.UTXEN   = 1; // Enable UART Transmitter
}
 
void Init_PWM(void)
{
    /**** PTCON: PWM Time Base Control Register ****/
    PTCONbits.PTEN   = 0;   // Timer Enable bit:            DISABLE MCPWM
    PWMCON1bits.PEN1H = 1;  // PWM1H (pin 37) is enabled for PWM output
    PWMCON1bits.PEN2H = 1;  // PWM2H (pin 35) is enabled for PWM output
    PTCONbits.PTCKPS = 1;// Input Clock Prescale bits:   1:4
    PTCONbits.PTOPS  = 0;   // Output Clock Postscale bits: 1:1
    PTCONbits.PTSIDL = 1;   // Stop in Idle Mode:           YES
    PTCONbits.PTMOD  = 0;   // Mode Select bits:            Free Running Mode
    PTCONbits.PTEN   = 1;   // Timer Enable bit:            ENABLE MCPWM
    
    /**** PTPER: PWM Time Base Period Register ****/
    PTPERbits.PTPER = 11250; // Period Value bits
}   
 
void DelayNmSec(unsigned int N)
{
    unsigned int j;
    while(N--)
    {
        for(j=0;j < MILLISEC;j++)
        {}
    }
}
 
 
// initialise ADC0 to read data
void adc0initialise()
{                         
  TRISBbits.TRISB0=1;
  ADPCFG = 0xFFFE;                    //   all PORTB = Digital; RB0 = analog
  ADCON1 = 0x0004;                    //   SAMP bit = 0 ends sampling ...
                                      //   and starts converting
  ADCHS    = 0x0000;                  //   Connect RB0/AN0 as CH0 input ..
                                      //   in this example RB2/AN2 is the input
  ADCSSL = 0;
  ADCON3 = 0x0002;                    // Manual Sample, Tad = internal 2 Tcy
  ADCON2 = 0x0000;
  //ADCON1=0x100;
  ADCON1bits.ADON = 1;                // turn ADC ON
}  
 
// initialise ADC1 to read data
//void adc1initialise()
//{                           
//  TRISBbits.TRISB0=1;
//  ADPCFG = 0xFFFD;                    //   all PORTB = Digital; RB1 = analog
//  ADCON1 = 0x0004;                    //   SAMP bit = 0 ends sampling ...
                                      //   and starts converting
//  ADCHS    = 0x0001;                  //   Connect RB1/AN1 as CH1 input ..
                                      //   in this example RB2/AN2 is the input
//  ADCSSL = 0;
//  ADCON3 = 0x0002;                    // Manual Sample, Tad = internal 2 Tcy
//  ADCON2 = 0x0000;
// //ADCON1=0x100;
//  ADCON1bits.ADON = 1;                // turn ADC ON
//}  
 
// initialise ADC2 to read data
//void adc2initialise()
//{                           
//  TRISBbits.TRISB0=1;
//  ADPCFG = 0xFFFC;                    //   all PORTB = Digital; RB2 = analog
//  ADCON1 = 0x0004;                    //   SAMP bit = 0 ends sampling ...
                                      //   and starts converting
//  ADCHS    = 0x0002;                  //   Connect RB2/AN2 as CH2 input ..
                                      //   in this example RB2/AN2 is the input
//  ADCSSL = 0;
//  ADCON3 = 0x0002;                    // Manual Sample, Tad = internal 2 Tcy
//  ADCON2 = 0x0000;
// //ADCON1=0x100;
//  ADCON1bits.ADON = 1;                // turn ADC ON
//}  
 
// read adata from ADC0
int adc0read()
{      
       ADCON1bits.SAMP = 1;            //   start sampling ...
       DelayNmSec(1);                //   delay
       ADCON1bits.SAMP = 0;            //   start Converting
       while (!ADCON1bits.DONE);       //   conversion done?
        
       return ADCBUF0;                 //   yes then get ADC value
}
 
// read adata from ADC1
//int adc1read()
//{    
//       ADCON1bits.SAMP = 1;            //   start sampling ...
//       DelayNmSec(1);                //   delay
//       ADCON1bits.SAMP = 0;            //   start Converting
//       while (!ADCON1bits.DONE);       //   conversion done?
        
//       return ADCBUF1;                 //   yes then get ADC value
//}     
 
// read adata from ADC2
//int adc2read()
//{    
//       ADCON1bits.SAMP = 1;            //   start sampling ...
//       DelayNmSec(1);                //   delay
//       ADCON1bits.SAMP = 0;            //   start Converting
//      while (!ADCON1bits.DONE);       //   conversion done?
        
//       return ADCBUF2;                 //   yes then get ADC value
//}

 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top