Not simple BLDC controller It RUNS! :)

GMUseless said:
RS-232 is actually +/- 3-15v. Less than 3v is 0, greater than 3 is is 1. Early on most PC's used 12V, so that became common. These days, many devices use 5v. USB is 5V, so your convertor is most likely 5v RS-232.
So I guess the first thing is I have to scope it. And see but its not likely they would step it up to 12v if I have a usb thats only 5 and all it needs is > and < 3 volts!
 
Arolo, sorry if I threw you off with the RS232, I just have a style of putting the interface on the dongle lead. That way I can throw a USB interface or true RS232 on the end if needed. Sometimes the PC has a 5v capable RS232, which isn't spec, but sometimes works. The true RS232 is a +-12 volt signal. Attached is the schematic for the true RS232 dongle to go with my previous schematic.
 

Attachments

  • RS232.pdf
    75.8 KB · Views: 63
Agree that having a conversation with your PIC is very important. Suggest using a Parallax 2 x 16 backlit display: runs on 5V, and positive serial logic driven directly from the PIC's serial port. This is a valuable tool to help debug stuff.
http://www.mouser.com/ProductDetail/Parallax/27977/?qs=uhQGOXNNFbZ1U1wly4B3DQ%3d%3d

Programming is C for the PIC is a must - the assembly language PIC will drive you crazy.

For all my starter pic projects I mount a parallax display in a Bud enclosure like this that already has a cutout fit for the parallax display:
http://www.mouser.com/Search/ProductDetail.aspx?R=PT-11754-DWvirtualkey56310000virtualkey563-PT-11754-DW

Once you have a serial display going, the PIC programming gets much easier.

Mark.
 
Arlo1 said:
Ok guys i used the curcuit scematic that bigmoose presented and i see alot of others use another chip between the main chip and the rs232 so im wondering can i just run the dspic30f3010 to my rs232 header with the apropriate caps and resistors?

For my 30F4011 project I use the simple schematic below. I know you're supposed to use the official
RS232 voltages using the IC BigMoose uses in his RS232 pdf file but in my setup with my usb-RS232
cable this works fine. Main thing to keep in mind is that you need to invert the signals to/from the
30F (as is done by this simple setup).

30F_to_rs232.jpg
 
I have not used a simulator or debugger in ages. They are far more trouble than they are worth (particularly simulators, which NEVER seem to get it right). I have found it to be much easier to just write perfect code without any bugs in it :roll:

I eat the elephant one byte at a time. Start with a very minimal program (like "Hello World") and build your application up in very small increments. I use print statements to find out what is and is not happening.
 
texaspyro said:
I have not used a simulator or debugger in ages. They are far more trouble than they are worth (particularly simulators, which NEVER seem to get it right). I have found it to be much easier to just write perfect code without any bugs in it :roll:

I eat the elephant one byte at a time. Start with a very minimal program (like "Hello World") and build your application up in very small increments. I use print statements to find out what is and is not happening.

++i;
 
A simulator is a wonderful thing :). I use it to test parts of the program, mainly the logic, but also to inject specific values as sensor/register readings and exercise the thing, including error situations. Much quicker than uploading and testing, and even allows for tests that are hard to do with the hw. Priceless tool.

I have used just 2 inverters like Lebowski and it usually works well with PCs (I've never found one that didn't work with this).
Just as a curiosity, I have even connected microcontrollers directly to PC's RS232 with just a series resistor between the PC's TX and uC's RX. And it works also, but there are caveats: the serial communication is bit banged in sw to invert the signals and, to ensure the electrical specs on uC, it must be powered before the PC and that uC circuit must have a minimum load (now find out why, heheheh).
 
Simulators are amazing for working on certain types of problems. But they are a huge time sink. I generally find that re-reading the documentation carefully solves the problem faster than setting up and simulating the problem. But the simulator can be useful until you learn how to interpret the documentation correctly.
 
pelle242 said:
About #2. In brief you first need to connect the pot to one of the AD inputs and ensure that it varies to voltage from 0 to 5 volts (or whatever your Vcc is). Then you have to set up the AD hardware inside the chip to use the pin as an AD (one pin can usually be programed to do several different things) This is done by writing values to specific memory locations (called peripheral registers). What addresses this registers have and what the specific bits in the registers do is in the big datasheet for the device you are using. The might also be some code from the vendor (microchip in this case) that you can build on to make it easier for you.

Once everything is configured right there will be one or two registers you can read to get the actual value of the voltage at the pin. If it is a 8 bit resolution converter you will get values from 0 to 255 for a 10 bit you will have to read two register and together they will form value from 0 to 1023.

To flash the LED there is the good way and the quick and dirty way. The quick way would be to set up a timer peripheral to generate interrupts and vary the timebase based on the AD value and then write an interrupt routine that will flash the LED.

The simple way is to write a "busy loop" function (it is called busy since the cpu cant do anything else during the delay) and the number of loops is based on the AD value.

Your program would be like:

Code:
void busyLoop(int loops) {

  volatile int i;

  for(i = 0; i < loops; i++) {}
}


void main(void) {
  
  unsigned int val;
  setupAD(); 
  setupLED(); 

  while(1) {
     ledOn(); 
     val = readAD();
     busyLoop(val);
    ledOf();
    busyLoop(val);  
  }
}

Please note, this is just from the top of my head, I have never coded C for dsPIC but the basic principle is the same regardless.
All the gritty details are in the functions that you have to code yourself or "steal" :)

Ok guys I worked on it and im reay lost. As I add functions I seem to be able to solve some of my warnings but in the hopes of speeding up the process can someone look at this and tell me whats wrong?
Goal = use AN2 as input for the 0-5v off the hall throttle and RD0 as LED out put.
Here is a link to a good page with dspic30f info I found http://ww1.microchip.com/downloads/en/DeviceDoc/70046D.pdf
Code:
#define   "p30F3010"
#include  "p30F3010.h"
//-----------------------------------------------------------------------------
//Configuration bits
_FOSC(CSW_FSCM_OFF & XT_PLL4);
_FWDT(WDT_OFF);
_FBORPOR (PBOR_OFF & PWRT_16 & MCLR_EN);
_FGS(CODE_PROT_OFF);
//-----------------------------------------------------------------------------
//Program Specific Constants
#define FCY 7372800 //Instruction cycle rate (Osc x PLL / 4)
//=============================================================================
//Main routine
void busyLoop(int loops) {

  volatile int i;

  for(i = 0; i < loops; i++) {}
}


void main(void) {

  
  unsigned int val;
ADPCFG = 0xFFFB; // all PORTB = Digital; RB2 = analog
ADCON1 = 0x0000; // SAMP bit = 0 ends sampling ...
// and starts converting
ADCHS = 0x0002; // Connect RB2/AN2 as CH0 input ..
// in this example RB2/AN2 is the input
ADCSSL = 0;
ADCON3 = 0x0002; // Manual Sample, Tad = internal 2 Tcy
ADCON2 = 0;
ADCON1bits.ADON = 1; // turn ADC ON
while (1) // repeat continuously
{
ADCON1bits.SAMP = 1; // start sampling ...
DelayNmSec(100); // for 100 mS
ADCON1bits.SAMP = 0; // start Converting
while (!ADCON1bits.DONE); // conversion done?
ADCValue = ADCBUF0; // yes then get ADC value
} // repeat
MOV 0xFF00, W0;  // configure port B as imput
 SetupAD() 
LATD = 0xfffe; //Initialize LED pin data to off state
TRISD = 0xfffe; //Set LED pin as output
LATDbits.LATD0 = 1; //Turn LED on
  while(1) {
    TRISD = (1);   
     busyLoop(val);
    TRISD = (0);
    busyLoop(val);  
  }
}
 
Arlo, if you have compiler warnings or errors you must copy&paste them here if you want help.
PIC isn't in my knowledge, but I find it strange to find an assembly instruction in the middle of your C program...

MOV 0xFF00, W0; // configure port B as imput

Also, please use indentation, it will make code reading sooooooo much easier.
 
Ok here you go I got to get to work but I will work on this tonight.
Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\Program Files (x86)\Microchip\mplabc30\v3.30c\bin\pic30-gcc.exe" -mcpu=30F3010 -x c -c "Arlo1.c" -o"Arlo1.o" -g -Wall
Arlo1.c:1:11: error: macro names must be identifiers
Arlo1.c:22: warning: return type of 'main' is not 'int'
Arlo1.c: In function 'main':
Arlo1.c:38: warning: implicit declaration of function 'DelayNmSec'
Arlo1.c:41: error: 'ADCValue' undeclared (first use in this function)
Arlo1.c:41: error: (Each undeclared identifier is reported only once
Arlo1.c:41: error: for each function it appears in.)
Arlo1.c:43: error: 'MOV' undeclared (first use in this function)
Arlo1.c:43: error: syntax error before numeric constant
Arlo1.c:44: warning: implicit declaration of function 'SetupAD'
Arlo1.c:45: error: syntax error before 'LATD'
Halting build on first failure as requested.
 
Arlo1 said:
Arlo1.c:1:11: error: macro names must be identifiers
No " on macro names.
Arlo1.c:22: warning: return type of 'main' is not 'int'
As the man says, main return type must be int (you have it void)
Arlo1.c: In function 'main':
Arlo1.c:38: warning: implicit declaration of function 'DelayNmSec'
Means it doesn't know about it, maybe wrong name or missing header file.
Arlo1.c:41: error: 'ADCValue' undeclared (first use in this function)
You have to declare your variables (before usage). That's basic C, you need to read half of a C book's chapter on variables.
Arlo1.c:41: error: (Each undeclared identifier is reported only once
Arlo1.c:41: error: for each function it appears in.)
Arlo1.c:43: error: 'MOV' undeclared (first use in this function)
Arlo1.c:43: error: syntax error before numeric constant
Arlo1.c:44: warning: implicit declaration of function 'SetupAD'
Arlo1.c:45: error: syntax error before 'LATD'
You need to terminate your C instructions with a ;
Halting build on first failure as requested.
 
Need to start simple and build up. Especially when starting out with new language, compiler, and chip. Until you get the hang of things just work with a few lines of code. Start with a simple working example first. Morph it gradually into what you want.

On the delay, need to include a header file before using the library function.

Best way to fix errors is to deal with the first couple and ignore the rest. Fix those then retest. The errors can compound and be unhelpful after the first few.
 
Man, you need to hit thoose C books again :) You mixed in assembler in your C code:

MOV 0xFF00, W0; is definitely asm.

Some (maybe helpful) comments:

Code:
void main(void) {

  unsigned int val;
  ADPCFG = 0xFFFB; // all PORTB = Digital; RB2 = analog     <-- Put in setupAD function
  ADPCFG = 0xFFFB; // all PORTB = Digital; RB2 = analog       <- this also
  ADCON1 = 0x0000; // SAMP bit = 0 ends sampling ... <- and this
  // and starts converting
  ADCHS = 0x0002; // Connect RB2/AN2 as CH0 input .. <- and this
  // in this example RB2/AN2 is the input
  ADCSSL = 0;                                                               
  ADCON3 = 0x0002; // Manual Sample, Tad = internal 2 Tcy <- and this
  ADCON2 = 0;
  ADCON1bits.ADON = 1; // turn ADC ON <- until here i guess..
  while (1) // repeat continuously                            
{                                                                           
ADCON1bits.SAMP = 1; // start sampling ...           <- Should be in a getAD() function
DelayNmSec(100); // for 100 mS                           <- replace with busyLoop();
ADCON1bits.SAMP = 0; // start Converting
while (!ADCON1bits.DONE); // conversion done?
ADCValue = ADCBUF0; // yes then get ADC value    <- ADCValue is a variable, must be devlared in the begining of function. Replace with val.
} // repeat                                                           <- until here
MOV 0xFF00, W0;  // configure port B as imput     <- need to go, replace with C code.
SetupAD()                                                            <- needs a ;
LATD = 0xfffe; //Initialize LED pin data to off state <- put into initLED() or initIO() function
TRISD = 0xfffe; //Set LED pin as output                  <- this also;
LATDbits.LATD0 = 1; //Turn LED on                       <- 
  while(1) {
    TRISD = (1);   
     busyLoop(val);
    TRISD = (0);
    busyLoop(val); 
  }
}
  ADCON1 = 0x0000; // SAMP bit = 0 ends sampling ...     <-- The cpu will never get down here, it is looping above.
  // and starts converting
  ADCHS = 0x0002; // Connect RB2/AN2 as CH0 input ..
  // in this example RB2/AN2 is the input 
  ADCSSL = 0;
  ADCON3 = 0x0002; // Manual Sample, Tad = internal 2 Tcy
  ADCON2 = 0;
  ADCON1bits.ADON = 1; // turn ADC ON
  while (1) // repeat continuously
{
ADCON1bits.SAMP = 1; // start sampling ...
DelayNmSec(100); // for 100 mS
ADCON1bits.SAMP = 0; // start Converting
while (!ADCON1bits.DONE); // conversion done?
ADCValue = ADCBUF0; // yes then get ADC value
} // repeat
MOV 0xFF00, W0;  // configure port B as imput
SetupAD()
LATD = 0xfffe; //Initialize LED pin data to off state
TRISD = 0xfffe; //Set LED pin as output
LATDbits.LATD0 = 1; //Turn LED on
  while(1) {
    TRISD = (1);   
     busyLoop(val);
    TRISD = (0);
    busyLoop(val); 
  }
}


If you want to I can install the same compiler as you have and hack together something that builds with comments etc but I totaly understand and respect if you want to continue doing it your own way. If so just ask away.
 
My ADC initialization routine: don't use it verbatim because it is coupled to timer 3 but it gives some example that works...
Code:
/*********************************************************************
void InitADC1(void)
ADC Initialization: For correct A/D conversions, the A/D conversion clock 
(TAD) must be selected to ensure a minimum TAD time of 153 nsec
10 bit 1 in 1024 resolution
*********************************************************************/
void InitADC1(void)
{
	ADPCFG 	= 0xFFF8; 									// port configuration RB0 to RB2 = analog

	//ADCON1 	= 0x0064; 									// PWM starts conversion, auto sampling
	ADCON1 	= 0x0044; 									// TIMER3 starts conversion, auto sampling
	//ADCON1 	= 0x00E4; 									// Autoconvert starts conversion, auto sampling

	ADCON2 	= 0x0000; 									// sample CH0 channel only

	ADCHS 	= 0x0002; 									// Connect RB2/AN2 as CH0 = pot.

	//ADCON3 	= 0x0080; 									// Tad = internal RC clock (4uS)
	ADCON3 	= 0x0005; 									// Tad=153nS rqd  ADCS=306/Tcy -1

	IFS0bits.ADIF 	= 0; 								// clear ADC interrupt flag
	IEC0bits.ADIE 	= 1; 								// enable ADC interrupt
	ADCON1bits.ADON = 1; 								// turn ADC ON

	T3CONbits.TON = 1; 									// start TMR3 to start ADC conversion
}
 
SO I have started over kinda. Here is where im at I have not figured out what to use to transform the ADC to a time delay yet but I will try to get that tomorow.
Code:
#define   "p30F3010"
#include  "p30F3010.h"
//-----------------------------------------------------------------------------
//Configuration bits
_FOSC(CSW_FSCM_OFF & XT_PLL4);
_FWDT(WDT_OFF);
_FBORPOR (PBOR_OFF & PWRT_16 & MCLR_EN);
_FGS(CODE_PROT_OFF);
//-----------------------------------------------------------------------------
//Program Specific Constants
#define FCY 7372800 //Instruction cycle rate (Osc x PLL / 4)
//=============================================================================
//Main routine
/*********************************************************************
int main(void)
{
LATD = 0xfffe; //Initialize LED pin data to off state
TRISD = 0xfffe; //Set LED pin as output
PORTDbits.RD0 = 1;        // alternate way 
unsigned int val;
ADC_Init();  // Init ADC
while (1)
    {
ADPCFG = 0xFFFB; // all PORTB = Digital; RB2 = analog
ADCON1 = 0x0000; // SAMP bit = 0 ends sampling and starts converting
ADCHS = 0x0002; // Connect RB2/AN2 as CH0 input in this example RB2/AN2 is the input
ADCSSL = 0;
ADCON3 = 0x0002; // Manual Sample, Tad = internal 2 Tcy
ADCON2 = 0;
ADCON1bits.ADON = 1; // turn ADC ON
ADCON1bits.SAMP = 1; // start sampling ...
DelayNmSec(100);    // for 100 mS
ADCON1bits.SAMP = 0;   // start Converting
while (!ADCON1bits.DONE);   // conversion done?
ADCValue = ADCBUF0;    // yes then get ADC value
return ADRESH;      //// return high byte of result
while(1) //Loop forever
  }
}

With that I get this.
----------------------------------------------------------------------
Release build of project `C:\Program Files (x86)\Microchip\Tps Led.mcp' started.
Language tool versions: pic30-as.exe v3.30, pic30-gcc.exe v3.30, pic30-ld.exe v3.30, pic30-ar.exe v3.30
Thu Dec 15 22:15:14 2011
----------------------------------------------------------------------
Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\Program Files (x86)\Microchip\mplabc30\v3.30c\bin\pic30-gcc.exe" -mcpu=30F3010 -x c -c "Arlo1.c" -o"Arlo1.o" -g -Wall
Arlo1.c:1:11: error: macro names must be identifiers
Arlo1.c:14:1: error: unterminated comment
Halting build on first failure as requested.
----------------------------------------------------------------------
Release build of project `C:\Program Files (x86)\Microchip\Tps Led.mcp' failed.
Language tool versions: pic30-as.exe v3.30, pic30-gcc.exe v3.30, pic30-ld.exe v3.30, pic30-ar.exe v3.30
Thu Dec 15 22:15:14 2011
----------------------------------------------------------------------
BUILD FAILED
Not understanding the macro names yet.

As well how do I build a C file from scratch??? I can only seem to open C files I have already.
 
And so I just found out about Sine/cosine or kinda is is something to look at? I was thinking using optical sensors but what would be better?
 
I must admit I started much simpler :oops: My first program on a new processor typically
makes a light connected to one pin go on when I press a button connected to another pin.
The second program I try to get the RS232 to transmit something, it's easy to see on a scope
whether there's activity on the TX pin.
 
Njay said:
Njay said:
Arlo1 said:
Arlo1.c:1:11: error: macro names must be identifiers
No " on macro names.
(...)

Just to expand on that,

in source file Arlo.c, line 1, column 11, macro name was expected but " was found instead.

A define is a macro, and macro names cannot start with the double quote character.
 
Alan B said:
Just to expand on that,

in source file Arlo.c, line 1, column 11, macro name was expected but " was found instead.

A define is a macro, and macro names cannot start with the double quote character.
Awesome thanks. I got rid of that one. It was that way I had incl # define "p30f3010" switched it to # define __p30f3010__ Only one problem left to solve. And add the rest of the code.
 
Lebowski said:
I must admit I started much simpler :oops: My first program on a new processor typically
makes a light connected to one pin go on when I press a button connected to another pin.
The second program I try to get the RS232 to transmit something, it's easy to see on a scope
whether there's activity on the TX pin.
I started with the pic kit lessons, then got the dspic30f3010 set up and got a LED to flash. So I feel after getting a LED to flash it would make sense to get it to flash at different speeds with a throttle. I want to learn the code I need for now all pertaining to a motor controller.

I do know I will want to use some sort of programmable software for a lot of things down the road so this is not just to learn to make a motor run.
Im already thinking about how to control a charging system for EVs and how to control solar power at my house and shop.
 
So with this code
Code:
#define  __p30F3010__
#include  "p30F3010.h"
#include  "adc10.h"
#include  "delay.h"
//-----------------------------------------------------------------------------
//Configuration bits
_FOSC(CSW_FSCM_OFF & XT_PLL4);
_FWDT(WDT_OFF);
_FBORPOR (PBOR_OFF & PWRT_16 & MCLR_EN);
_FGS(CODE_PROT_OFF);
//-----------------------------------------------------------------------------
//Program Specific Constants
#define FCY 7372800 //Instruction cycle rate (Osc x PLL / 4)
//=============================================================================
//Main routine
//*********************************************************************
//Main routine
void busyLoop(int loops) {

  volatile int i;

  for(i = 0; i < loops; i++) {}
}


int main(void) {
{
LATD = 0xfffe;        //Initialize LED pin data to off state
TRISD = 0xfffe;       //Set LED pin as output
PORTDbits.RD0 = 1;        // alternate way 
unsigned int val;
ADC_Init();              // Init ADC
while (1)
}   
 {
ADPCFG = 0xFFFB;    // all PORTB = Digital; RB2 = analog
ADCON1 = 0x0000;    // SAMP bit = 0 ends sampling and starts converting
ADCHS = 0x0002;     // Connect RB2/AN2 as CH0 input in this example RB2/AN2 is the input
ADCSSL = 0;
ADCON3 = 0x0002;    // Manual Sample, Tad = internal 2 Tcy
ADCON2 = 0;
ADCON1bits.ADON = 1; // turn ADC ON
ADCON1bits.SAMP = 1; // start sampling ...
DelayNmSec(100);     // for 100 mS
ADCON1bits.SAMP = 0;   // start Converting
while (!ADCON1bits.DONE);   // conversion done?
ADCValue = ADCBUF0;    // yes then get ADC value
return ADRESH;       // return high byte of result
while(1)             //Loop forever
 } 
}
I now get this.
Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\Program Files (x86)\Microchip\mplabc30\v3.30c\bin\pic30-gcc.exe" -mcpu=30F3010 -x c -c "Arlo1.c" -o"Arlo1.o" -g -Wall
Arlo1.c: In function 'main':
Arlo1.c:32: warning: implicit declaration of function 'ADC_Init'
Arlo1.c:34: error: syntax error before '}' token
Arlo1.c:31: warning: unused variable 'val'
Arlo1.c:44: warning: implicit declaration of function 'DelayNmSec'
Arlo1.c:47: error: 'ADCValue' undeclared (first use in this function)
Arlo1.c:47: error: (Each undeclared identifier is reported only once
Arlo1.c:47: error: for each function it appears in.)
Arlo1.c:48: error: 'ADRESH' undeclared (first use in this function)
Arlo1.c:50: error: syntax error before '}' token
Arlo1.c:51: warning: control reaches end of non-void function
Halting build on first failure as requested.
----------------------------------------------------------------------
Release build of project `C:\Program Files (x86)\Microchip\Tps Led.mcp' failed.
Language tool versions: pic30-as.exe v3.30, pic30-gcc.exe v3.30, pic30-ld.exe v3.30, pic30-ar.exe v3.30
Fri Dec 16 07:42:46 2011
----------------------------------------------------------------------
BUILD FAILED
 
There are bracket problems with the while(1) statements. Also you have two of them... when implemented right, they are infinite loops unless you jump out of them, so you really only want one... I'll try to fix some of this today if crisis do not overtake me...

Another issue:
ADC_Init(); // Init ADC

This line is a "subroutine call" and the function ADC_Init(); is never defined prior to use. As you would imagine, that makes a mess of things.
 
Back
Top