chipKIT® Development Platform

Inspired by Arduino™

ChipKit Uno32 - car brain

Created Sun, 27 Nov 2011 22:59:46 +0000 by slayer1991


slayer1991

Sun, 27 Nov 2011 22:59:46 +0000

Hello!

I chose the Uno32 instead of the Arduino because it has more power. The goal of this project is to build a Data Acquisition and Dashboard control system for a SAE Baja.

I want to gather info from several sensors (wheel speed, rpm, fuel gauge), record the data on a SD card and output some info onto the dashboard.

The dashboard will have 10 leds for fuel gauge and 21 leds speed and a 4 digit 7 segments display (speed, distance traveled etc), controled by 4xTLC5940. Maybe later I will implement a GPS module and real time data transfer (wifi or radio).

I was planning to use some LM3914 but the TLC library took all the timers available for PWM/OC. So I'm only gonna use those. I am trying to change the library though to free the SPI pins so I can add the SD card there. More soon!

So I'm using SPI1 for TLCs now. Aand I managed to use the SD card separately on SPI2. I will try them together, though I don't find a reason why it shouldn't work.

Next on the list: testing it all together.

Thanks!


Jacob Christ

Mon, 28 Nov 2011 01:27:18 +0000

I need help, either making PWM work or some ideas.

To get things going and verify hardware you could just use a delay command...

Something like this:

void setup() {
  // put your setup code here, to run once:
  pinMode(13,OUTPUT);
}

void loop() {
// put your main code here, to run repeatedly: 
  digitalWrite(13, HIGH);
  delay(10);
  digitalWrite(13,LOW);
  delay(90);
}

There are a few threads on the message board talking about more advanced PWM.

Also, when you have you mini baja car up an running with MIDI ports I want to see a picture! You should put a little hatch on the outside labeled MIDI.

Jacob


slayer1991

Mon, 28 Nov 2011 01:50:59 +0000

I'm going to put that advanced pwm to test. I could play a tune on a small speaker. Tomorrow I will try to output a 0-2.4 V PWM to display engine RPM on 20 leds (I've got 2xLM3914, so why not). Native analogWrite is a dream to me right now. Are there libraries for I2C led controllers by any chance? I would use one to drive my LM3914 and the other ports for the display. This seems like a decent workaround.. Also I found a PWM shield (google it, by Practical Maker). I don't think it will work though, will it?


Jacob Christ

Mon, 28 Nov 2011 07:00:07 +0000

I'm going to put that advanced pwm to test. I could play a tune on a small speaker.

If you want to play a tune using PWM's check out this this:

http://www.youtube.com/watch?v=8LdxwfSsjZM

Are there libraries for I2C led controllers by any chance? I would use one to drive my LM3914 and the other ports for the display. This seems like a decent workaround..

I haven't had a chance to play with I2C on the chipKIT boards yet, and the wiki list the I2C stats as Semi-OK right now. Maybe someone that is using it more can better comment.

http://www.chipkit.cc/wiki/index.php?title=Library_Status

Also I found a PWM shield (google it, by Practical Maker). I don't think it will work though, will it?

How many PWM's do you need, what duty cycle range and period? There is code out there that will turn every pin of a Max32 into a PWM driver for an RC servo. So unless you need more PWM's than there a pins on the chip you probably can skip this shield, though it probably can be made to work.

http://www.youtube.com/watch?v=q2GlwfWwr3w

EDIT: Looked at the datasheet for the TI chip used on the shield a bit more. Since Arduino's are 5V logic and chipKIT's are 3.3V logic you need to check if a logic levels are compatible. In this case the TI chip expects 0.8 * Vcc for a valid logic 1 and when powered from 5V this is 4V so a 3.3V logic 1 from a PIC32 will not be valid, also, I think a PIC32 logic 1 starts around 2.4V so this is way below 4V. The board probably will need to be modded a bit to make it run on 3.3V (which the TI PWM chip can do).

Jacob


slayer1991

Mon, 28 Nov 2011 15:54:31 +0000

If you want to play a tune using PWM's check out this this:

Been there, done that. I just need a small amp for a 8 ohm 2 w speaker I saved from a destroyed GPS unit. Found one on google, pretty simple.

I haven't had a chance to play with I2C on the chipKIT boards yet, and the wiki list the I2C stats as Semi-OK right now. Maybe someone that is using it more can better comment.

Yes, I found that. I want some specific applications before I buy an I2C led driver.

How many PWM's do you need, what duty cycle range and period? There is code out there that will turn every pin of a Max32 into a PWM driver for an RC servo. So unless you need more PWM's than there a pins on the chip you probably can skip this shield, though it probably can be made to work. EDIT: Looked at the datasheet for the TI chip used on the shield a bit more. Since Arduino's are 5V logic and chipKIT's are 3.3V logic you need to check if a logic levels are compatible. In this case the TI chip expects 0.8 * Vcc for a valid logic 1 and when powered from 5V this is 4V so a 3.3V logic 1 from a PIC32 will not be valid, also, I think a PIC32 logic 1 starts around 2.4V so this is way below 4V. The board probably will need to be modded a bit to make it run on 3.3V (which the TI PWM chip can do).

The Max32 PWM code did not work. I tried the Simple PWM example, chose OC1 on my Uno but it just won't drive the LM3914s right. It would just dim all 20 leds. I think it is because the PWM frequency is to high, but that's just my opinion.

I also found an example to fade a led:

/*
Fade
This example shows how to fade an LED on pin 9
using the analogWrite() function.
This example code is in the public domain.
*/
int brightness = 1; // how bright the LED is
int fadeAmount = 1; // how many points to fade the LED by

void setup() { 
// declare pin 3 to be an output:
pinMode(3, OUTPUT);
// Open Timer2, 1:1 w/2048 tick interval (for 11-bit PWM)
OpenTimer2(T2_ON | T2_PS_1_1,2048);
OpenOC1(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE,
0,0);
}

void loop() { 
// set the brightness of pin 3:
SetDCOC1PWM(brightness); 
// change the brightness for next time through the loop:
brightness = brightness + fadeAmount;
// reverse the direction of the fading at the ends of the fade: 
if (brightness == 1 || brightness == 2047) {
fadeAmount = -fadeAmount ; 
} 
// wait for 5 milliseconds to see the dimming effect 
delay(5); 
}

by CNCaddict

This one lights up my leds in a sequence, like a bar graph, which means it works outputing a PWM. This is the one I will try today. I read the RPM with this circuit (google: e98a034, it's a pdf, first url) on an analog pin and then output a PWM voltage to drive the leds. My second test will be to take the signal from the circuit and input it in both the led drivers and the Uno, so I only record the RPM and not drive the leds.

LE: also, maybe I can use some code from the Pinguino PIC32. It states that it is compatible with arduino code, it's worth a shot.


photomankc

Mon, 28 Nov 2011 16:42:45 +0000

I'm using mine as an I2C slave to control two stepper motors for a robot and take commands from a master device for what speed and distance to move the motors.

I don't think you'll have any difficulty with I2C as the master. The main issue that I have run into is that as a SLAVE the Uno32 does not wait for all the data to arrive and then signal the interrupt handler, it instead triggers the ISR for each byte recieved after the slave address which is quite different to how you handle in on the Arduino. But for a master running the line that's not an issue you already know how many bytes you are sending and requesting. Just remember that you have to set the jumpers to the RG side to get I2C on those two pins.


slayer1991

Mon, 28 Nov 2011 17:44:51 +0000

Thanks photomank! That is my backup option, an I2C led driver.

Right now I might have found 2 analog outputs! 2x 4 bit, VREF+ and VREF- on pins 41 and 42. If they are independent of each other (vref+ might be equal to the absolute value of vref-) it's 2 outputs. If they are the same, but opposite signs then at least that is one output. It gives out 0-3.3V in 16 steps. At least that is what the PIC32 manual says. I will test those too in a couple of hours.


GeneApperson

Mon, 28 Nov 2011 18:35:27 +0000

Thanks photomank! That is my backup option, an I2C led driver. Right now I might have found 2 analog outputs! 2x 4 bit, VREF+ and VREF- on pins 41 and 42. If they are independent of each other (vref+ might be equal to the absolute value of vref-) it's 2 outputs. If they are the same, but opposite signs then at least that is one output. It gives out 0-3.3V in 16 steps. At least that is what the PIC32 manual says. I will test those too in a couple of hours.

VREF+ and VREF- are inputs to the A/D converter. Those pins can be used either as normal analog input channels or as reference inputs for the a/d. The VREF+ can be selected as a reference using the analogReference() function. There currently isn't any function in the hardware abstraction layer to select VREF-. The A/D converter on an AVR device doesn't have any notion of setting the low voltage reference on its A/D.

VREF+ sets the upper voltage limit of the a/d converter. I.e. with VREF- set to 0 (the default), then 0 volts into an analog channel converts to the value 0, VREF/2 volts into the analog input coverts to ~512 and VREF volts into the analog input converts to ~1023.

Setting VREF- sets the lower limit of the a/d converter.

For example, with VREF- set to 1V and VREF+ set to 2V, then a 1V input converts to 0, a 1.5V input converts to ~512, and a 2V input converts to ~1023. VREF- and VREF+ are set by applying the desired voltage to the pin, and setting the appropriate bits in one of the A/D converter control registers to select external references for VREF+ and VREF-. As I said, analogReference() can be used to select using the VREF+ pin as an external reference. There is currently no function to do that for VREF-. I need to add one.

Gene


slayer1991

Mon, 28 Nov 2011 18:42:27 +0000

And I tought I could get an output there.. too bad. Any chance of having the regular analogwrite fixed soon?


GeneApperson

Mon, 28 Nov 2011 19:19:12 +0000

Oops...

I was just looking at the analogReference code and I realize that there was an error in my previous post.

The chipKIT analogReference function accepts the following parameter values for setting references:

EXTERNAL - select VREF+, AVss as the references EXTMINUS - select AVdd, VREF- as the references EXTPLUSMINUS - select VREF+, VREF- as the references DEFAULT - AVdd, AVss as the references.

So, I was wrong about there being no way to select VREF- as a reference. I had forgotten that I put that in back in June.

Gene Apperson Digilent


slayer1991

Wed, 30 Nov 2011 00:51:00 +0000

I will show you 2 videos what the LM3914 does and what it should do. The first one [url]http://www.youtube.com/watch?v=7jHlSB6RLHc[/url] uses the fade example. The second one [url]http://www.youtube.com/watch?v=HxPuAa4e3Xg[/url] uses the SoftPWM 3 pin example.

I would like to have the functionality of the first one (bar graph, as it should actually be) while I can output info as in the second one.

LE: the 10th led doesn't light up because the reference voltage is 3.36. Wrong resistor calculator:D


EmbeddedMan

Wed, 30 Nov 2011 21:27:23 +0000

By SoftPWM do you mean the SoftPWMServo library that comes with MPIDE? If so, then there should be no reason you can't duplicate the first example with the SoftPWMServo library.

*Brian


slayer1991

Wed, 30 Nov 2011 23:09:16 +0000

By SoftPWM do you mean the SoftPWMServo library that comes with MPIDE? If so, then there should be no reason you can't duplicate the first example with the SoftPWMServo library. *Brian

Yes, the SoftPWMServo library. I think it just ain't working yet. I'm waiting for some TLC5940 in the meantime. I shall use those to control LEDs or maybe even the lm3914s and some 7 segment common anode digits.


EmbeddedMan

Thu, 01 Dec 2011 03:20:32 +0000

Slayer,

All of the testing I've done on SoftPWMServo shows that it is working fine. Can you send some example code where it's not working? I'd love to find any bugs in it so we can get it fixed, but so far, nobody has been able to send me any code that shows a failure of any type.

*Brian


slayer1991

Thu, 01 Dec 2011 04:19:39 +0000

#include <SoftPWMServo.h>

const int PinOne = 3;
char PinOneValue = 0;
 
void setup() 
{} 
 
void loop() 
{ SoftPWMServoPWMWrite(PinOne, PinOneValue);
  PinOneValue++;
  delay(15);
}

This is what I used and got the second video. The code on the first page, the fade one, lights up the leds one at a time. SoftPWM all at once but at a different brightness. I think it's the chips somehow. Maybe the fade example updates at a higher frequency and SoftPWM only does 490. How can I change the SoftPWM to a higher frequency and try?


EmbeddedMan

Thu, 01 Dec 2011 19:58:52 +0000

Can you send me to the code that was used to make the first video?

I would expect that the PWM value from your posted SoftPWMServo code would ramp the from 0 to 255 (0% o 100%) over the course of 3.84s (15ms * 256 iterations). Instead, it looks like it is ramping about once per second.

I'll take a look at this and see if I can duplicate your results.

*Brian


slayer1991

Thu, 01 Dec 2011 21:03:11 +0000

Can you send me to the code that was used to make the first video? I would expect that the PWM value from your posted SoftPWMServo code would ramp the from 0 to 255 (0% o 100%) over the course of 3.84s (15ms * 256 iterations). Instead, it looks like it is ramping about once per second. I'll take a look at this and see if I can duplicate your results. *Brian

Don't worry, I modified the delay when I took the video. The code for one at a time lighting is on the first page of the topic. I think SoftPWMServo simply doesn't work with the LM3914. Might be because of the frequency, I have no idea.If you have an LM maybe you can figure it out. If not, don't bother, because my multimeter read a nice uniformly increasing voltage with your library. Haven't tried to measure the fade code voltage though. I will do it later today. If I could measure the frequency of the fade one, I would.


EmbeddedMan

Thu, 01 Dec 2011 23:14:24 +0000

Ahh, OK, things are making a lot more sense now. I guess I just couldn't follow what you were trying to do accurately - there is a lot of information in these two pages of posts.

After reviewing what you did in the first video (used HARDWARE PWM to drive the bar graph display), I can tell you that I do NOT expect the SoftPWMServo library to be able to do the same thing. The PWM in hardware is far, far, far faster than the SoftPWMServo (which is only 490Hz). That's why it works for the hardware and won't work for SoftPWMServo. So I don't think there's anything wrong with the library at all.

If you want it to work, you should use hardware PWM, as it will be a lot faster and will work fine with your LM3419 chips. I think there are some examples here on this forum for talking directly to the PIC32 PWM/Timer hardware.

*Brian


Ganapoes

Mon, 05 Dec 2011 06:04:14 +0000

And I tought I could get an output there.. too bad. Any chance of having the regular analogwrite fixed soon?


EmbeddedMan

Mon, 05 Dec 2011 11:52:48 +0000

Is it broken? I just tried the following program on my Uno32 and it worked as expected:

int brightness = 50;    // how bright the LED is
int fadeAmount = 1;    // how many points to fade the LED by

void setup()  { 
  // declare pin 9 to be an output:
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
} 

void loop()  { 
  // set the brightness of pin 9:
  analogWrite(3, brightness);    
  analogWrite(5, brightness);    
  analogWrite(6, brightness);    
  analogWrite(9, brightness);    
  analogWrite(10, brightness);    
  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade: 
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  delay(1);
}

*Brian


slayer1991

Tue, 06 Dec 2011 23:07:41 +0000

Ok. My mistake was taking the PWM directly as an analogue voltage. If I add an RC filter I can do that, and then I will have no problems with SoftPWM (I think, has to be tested.).

Right now the TLC5940 is the one that gives me a headache. I wired it exactly like this [url]https://github.com/ColinHarrington/tlc5940chipkit/blob/master/breadboard-chipkit-tlc5940.png[/url], checked and double checked. I even added an external power source for a single TLC. The LEDs are 3 V, does this matter? I tried different codes, but I can't get a single LED to light up. Any input on this prooblem?

LE: my TLC does not sink any current! put an ampermeter instead of an led and it stays at 0.. LE2: if I take out the pull-up resistor I can make the LEDs flicker by touching the chipkit pins with my hand.


KM6VV

Tue, 06 Dec 2011 23:39:37 +0000

Yeah, for some reason the "Arduino" world thinks PWM out is an analog signal! OK, maybe close enough after a little filtering. But if you've ever worked with a D/A module (chip)...

Alan KM6VV


slayer1991

Wed, 07 Dec 2011 01:10:13 +0000

Yeah, for some reason the "Arduino" world thinks PWM out is an analog signal! OK, maybe close enough after a little filtering. But if you've ever worked with a D/A module (chip)... Alan KM6VV

I know it's a cheap approximation of an analog signal, but it's close enough for what I need. I will drive the LM3914 using an RC filter with a settling time of 2-5 seconds and minimum ripple (0-10 mV). I will try the setup as soon as I have the chance.


slayer1991

Wed, 11 Jan 2012 01:09:19 +0000

59A lil update. The LM3914 with an RC circuit works really well. The downside is that it doesn't work together with the TLC5940, so I'll only use those. Right now I'm looking into adding an SD card but I don't know if it works with TLC5940.

I am waiting for some responses on the forum and the SD slot from sparkfun. Then I will try something myself.


slayer1991

Thu, 19 Jan 2012 01:54:26 +0000

The more I learn, the closer I come to the end of my project. PWM (analogWrite) pins use timer 2, which is also used in the TLC5940 library. That's why I can't run my LM3914 together with the TLC.

I am also interested in having an SD card connected. So I looked into the library of the TLC and tried to modify it to use SPI1 (what?!!?).

Uno32 comes with 2 SPIs. SPI2 is wired to pins 10-13 like an Arduino. SPI1 on the other hand is hidden around. It uses pins 14 (A0) for SS, 0 for data in, 1 for data out (looks like it uses UART1 pins by applying the SPI comm protocol) and 38 for SCLK1.

I modified parts of the library trying to use other timers (couldn't do, as timers 2 and 3 are the only one that can be used for PWM-OC). Then I tried to move the SPI2 pins away and to SPI1 pins. The biggest problem was understanding PORTx, TRISx, and all those HEX numbers and how are they connected to the actual pins. I think I figured it out, I'll test it tomorrow.

If you need the library file, check my post in the Libraries forum.

LE: test working! Using SPI1 to drive the TLC5940.