Jump to content
43oh

A Noobs Introduction to MSP430 - Serial RC Car Video Blog


Recommended Posts

Hello people.

I've been experimenting with the msp430, and working toward a goal. But thought i'd document every step. That way creating a complete video blog of the project, from the first steps, to hopefully something unique.

 

So for now this is mainly for people new to microcontrollers and are interested in the Launchpad, or just bought one and don't know what to do with it. 43oh veterans: Probably not for you, but if you see errors in the video's please tell me so i can insert notes about them for future viewers :)

 

Enjoy!:

 

MarkoeZ MSP430 Launchpad Video's Part 1: Audio Intro

 

MarkoeZ MSP430 Launchpad Video's Part 2: First part of the package contents

 

MarkoeZ MSP430 Launchpad Video's Part 4: The Standard Temperature Sensing Program(with pc serial connection)

 

MarkoeZ MSP430 Launchpad Video's Part 5: Leds and Buttons

 

MarkoeZ MSP430 Launchpad Video's Part 6: Leds controlled through PC Serial Connection

 

MarkoeZ MSP430 Launchpad Video's Part 7: Soldering, connections, and more

 

MarkoeZ MSP430 Launchpad Video's Part 8: Created my LaunchPad Plugon Test Board

 

MarkoeZ MSP430 Launchpad Video's Part 9: PC Soundcard Oscilloscope for testing:

 

MarkoeZ MSP430 Launchpad Video's Part 10: Introducing a Porsche (rc car) Loud Noise Warning!!

 

MarkoeZ MSP430 Launchpad Video's Part 11:RC Car controlled through PC Serial. Loud Noise Warning!!

 

MarkoeZ MSP430 Launchpad Video's Part 12: Serial RC car, added connectors and first drive test!

 

MarkoeZ MSP430 Launchpad Video's Part 13: The first Sensor, Cheap, but working, IR LED Collision Detection

 

MarkoeZ MSP430 Launchpad Video's Part 14: Started work on the Car Drive Program *Noise Warning!*

 

MarkoeZ MSP430 Launchpad Video's Part 15: Introducing an OpenPandora and an FT232RL usb to serial chip

 

MarkoeZ MSP430 Launchpad Video's Part 16A: Created plugin sensors

 

MarkoeZ MSP430 Launchpad Video's Part 16B: Plugin IR sensor test, and tools overview

 

MarkoeZ MSP430 Launchpad Video's Part 17: Porsche with USB! Hardware building and status overview

 

MarkoeZ MSP430 Launchpad Video's Part 18: Standalone G2252 First Tests, serial communication too

 

MarkoeZ MSP430 Launchpad Video's Part 19: MSP on batteries, Main Board for the car updated with IR, power led and more

 

MSP430 Launchpad Video 20: Porsche Nightrider Shiftregister

 

MSP430 Launchpad Video 21: PWM On Board Leds, controlled by launchpad Serial

 

MSP430 Launchpad Video 22: Added a button to the car and cut up the board

 

MSP430 Intermediate 23: First Drive Test of the RC Porsche standalone!

 

EDIT March-2-2012: Just noticed i never added the final thing. So, here it goes!

 

My Contest Entry:

 

A Porsche Model Car with an MSP430G2252, movement, speed and (just for fun) shiftregister LEDs controlled over usb Serial by a Pandora Console.

With custom written Gui, And Touchscreen, D-Pad and ActionButton drive/program select.

And yes, wireless is next, but still deciding what hardware i want.

 

But the Video's show it pretty well, Enjoy!

 

Drive Tests:

 

Software overview and Final tests before drive:

 

Some other video's i kept private till now:

 

Very first Pandora gui test:

 

First PC serial test with all modules connected, also nice overview of the individual modules:

 

 

From the pandora you have basic drive control obviously, but also the PWM can be adjusted by single values, or 6 pre set steps, starting at 0 and increasing 20% with each step, and slider/buttons for quick selection.

Also, just for fun, i added some commands to change the led blinking mode :)

 

Components:

 

MSP430 Main Car Control and Interface Board - Contains all the connections for the individual modules, as well as the Controller

Parts:

* 1 MSP430G2252

* 1 20 pin DIP Chipsocket

* 4 NPN Transistors

* 4 2.2kohm Resistors

* 1 33kohm Resistor

* 1 470ohm Resistor

* 1 470nF Capacitor

* 1 Orange T1 LED

* About a row of male Pin Headers

* lots of connection cables (i use old hard drive IDE cables for everything)

 

 

Shift Register Led Control Board - A shift Register built onto a small module containing all resistors for led drive

Parts:

* 1 74HC595 Shift Register

* Chipsocket optional, i just soldered onto the board

* 6 1kohm resistors (for the slightly dimmed knightrider leds, and one for the board power led)

* 1 Orange T1 LED

* about 1/4 of a row of male Pin Headers

* connection cable (i use old hard drive IDE cables for everything)

* min 5 port female Pin Header

 

FT232R BreakoutBoard by Sparkfun

Simply soldered male Pin Headers to it, and glued female headers with a cable inside the car. Instant usb module.

 

Built into the car:

* 5x T1 LED for the knightrider effect

* 1 pushbutton

* 5 pin female header with connection cables for the usb->serial module glued in.

 

An OpenPandora - Gui is only functional for pandora atm. But any device capable of USB serial can drive it, using a terminal, or a Gui. It's only sending out to the car atm, so a simple "echo blabla" is enough.

 

First rough schematics, Mind that these are the first schematics i have ever drawn in my life. I would like some constructive critics, but be gentle ;)

 

[attachment=0]PandoraPorschechematics.png[/attachment]

 

And the code, again, might be rough at the edges:

#include 
#include "stdbool.h"

#include  //add for interrupt
#define PERIOD 200  //defines frequency
volatile  int timer = 0; //counts how many interrupts have been called
//resets when it counts to PERIOD
volatile  int duty_cycle = 90;// max = PERIOD - 1 and min = 1

#define		TXD			BIT1    // TXD on P1.1
#define		RXD			BIT2	// RXD on P1.2

#define		Bit_time		104	// 9600 Baud, SMCLK=1MHz (1MHz/9600)=104
#define		Bit_time_5		52	// Time for half a bit.

// Code for the ShiftRegister driving the LED's
#define		SHIFTDATA		BIT7	// Shiftregister Data on P1.7
#define		SHIFTCLOCK		BIT7	// Shiftregister Clock Pulse on P2.7
#define		SHIFTLATCH		BIT6	// Shiftregister Latch Pulse on P2.6

#define 	STEERLEFT		BIT4	// Left steering on P2.4
#define  	STEERRIGHT		BIT5	// right steering on P2.5

bool shiftbit[8];		// array used to contain the shiftregister serial bits
int activeled = 0;		// used for led animation
bool ledup = 1;			
int ledcounter = 0;
int shifttimer = 0;		// Timer to control shiftregister output speeds

int blinkmode = 0;		// 0 is knightrider, 1 is up and down bar, 2 is blinketyblink
int steeringmode = 0;  // 0 is neutral, 1 is left, 2 is right (right broken here though) 

void pulseShiftClock ( void );
void pulseShiftLatch ( void );
void setShiftReg ( void );


// ASCII values for the commands
#define		MODE0			0x30		// serial 1
#define		MODE1			0x31		// serial 1
#define		MODE2			0x32		// serial 2
#define		MODE3			0x33		// serial 3
#define		MODE4			0x34		// serial 4
#define		MODE5			0x35		// serial 5
#define		MODE6			0x36		// serial 6		
#define		MODE7			0x37		// serial 7
#define		MODE8			0x38		// serial 8

#define		PWMMODE0		0x61		// serial a
#define		PWMMODE1		0x62		// serial b
#define		PWMMODE2		0x63		// serial c
#define		PWMMODE3		0x64		// serial d
#define		PWMMODE4		0x65		// serial e
#define		PWMMODE5		0x66		// serial f

#define 	BLINKMODE0		0x69		// serial i
#define		BLINKMODE1		0x6A		// serial j
#define		BLINKMODE2		0x6B		// serial k

#define LED_SENSE INCH_6	// Photodiode connected to P1.6

unsigned int adcval = 0;	// used for light sensing, nor really used in this case
unsigned int timerCount = 0;// tomer for the sensing

unsigned char BitCnt;		// Bit count, used when transmitting byte
unsigned int TXByte;		// Value sent over UART when Transmit() is called
unsigned int RXByte;		// Value recieved once hasRecieved is set

unsigned int drivestate = 0;// Dive neutral, forward or backward

unsigned int i;			// for loop variable

bool isReceiving;		// Status for when the device is receiving
bool hasReceived;		// Lets the program know when a byte is received

void Transmit(void);
void Receive(void);

unsigned int analogRead(unsigned int pin) {	// analog reading code, not really used in this case

 ADC10CTL0 = ADC10ON + ADC10SHT_2 + SREF_1 + REFON + REF2_5V;
 ADC10CTL1 = ADC10SSEL_0 + pin;

 ADC10CTL0 |= ENC + ADC10SC;

 while (1) {
   if ((ADC10CTL1 ^ ADC10BUSY) & ((ADC10CTL0 & ADC10IFG)==ADC10IFG)) {
     ADC10CTL0 &= ~(ADC10IFG +ENC);
     break;
   }
 }

 return ADC10MEM;
}


void main(void)
{

unsigned int i, delay;
WDTCTL = WDT_MDLY_0_064; // Watchdog Timer interval setting

if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
{
	while(1); // If cal constants erased, trap CPU!!
}
BCSCTL1 = CALBC1_1MHZ; 		// Set range
DCOCTL = CALDCO_1MHZ; 		// Set DCO step + modulation



P1SEL |= TXD;				// Connected TXD to timer
P1DIR |= TXD;

P1IES |= RXD;				// RXD Hi/lo edge interrupt
P1IFG &= ~RXD;				// Clear RXD (flag) before enabling interrupt
P1IE |= RXD;



//P1DIR = 0X41;               // set both leds to output
                  			// and set them off initially

P2DIR |= 0X0A; 				//set P2 Drive pins
P2DIR |= STEERLEFT;
P2DIR |= STEERRIGHT;

P1DIR |= SHIFTDATA;               // set shiftregister data pin output  
P2DIR |= SHIFTCLOCK;               // set shiftregister clock and latch pins to output
P2DIR |= SHIFTLATCH;
P2SEL = 0x00;							// allow 2.6-2.7 to output
P1OUT = 0;						// Set both ports outputs to zero initially
P2OUT = 0;

isReceiving = false;			// Set initial values
hasReceived = false;


IE1 |= WDTIE;
__enable_interrupt();				// Enable interrupts

__bis_SR_register(GIE);			// interrupts enabled\


while(1)
{
	shifttimer++;
	if (shifttimer == 2000)		// The led animation and shiftregister main loop code
	{

		shifttimer = 0;

		if (blinkmode == 0 )
		{
			if (ledup == 1)
	   		{
	   			activeled++;
	   			if(activeled == 4){ledup = 0;}	
	   		}
	   		else
	   		{
	   			activeled--;
	   			if(activeled == 0){ledup = 1;}
	   		}
	   		for (i = 0; i < 8;i++)
	   		{
	   			if (i == activeled)
	   			{
	   				shiftbit[i] = 1;
	   			}
	   			else
	   			{
	   				shiftbit[i] = 0;
	   			}
	   		}	   		
		}
		else if (blinkmode == 1)
		{
			if (ledup == 1)
	   		{
	   			activeled++;
	   			if(activeled == 4){ledup = 0;}	
	   		}
	   		else
	   		{
	   			activeled--;
	   			if(activeled == 0){ledup = 1;}
	   		}
	   		for (i = 0; i < 8;i++)
	   		{
	   			if (i <= activeled)
	   			{
	   				shiftbit[i] = 1;
	   			}
	   			else
	   			{
	   				shiftbit[i] = 0;
	   			}
	   		}	   		
		}
		else if (blinkmode == 2)
		{
			for (i = 0; i < 8;i++)
	   		{
	   			if (shiftbit[i] == 0)
	   				{
	   					shiftbit[i] = 1;
	   				}
	   			else {shiftbit[i] = 0;}
	   		}

		}
   		setShiftReg();
	}

	if (hasReceived)		// If the device has recieved a value
	{
		Receive();
	}
	if (drivestate == 9)	// the sensing mode, not really used in this case
	{
		adcval = 0;
		for ( i=0; i < 8; i++ ) {
			adcval += analogRead(LED_SENSE );	// Read the analog input.

			delay = 1000;
			while (--delay);
		}

		if (adcval < 800 ){
			drivestate = 1;
			duty_cycle = 110;
			delay = 1000000000;
			while (--delay);
			delay = 1000000000;
			while (--delay);
			delay = 1000000000;
			while (--delay);
			duty_cycle = 90;
			drivestate = 0; 
		}							

	}
}
}
/**
* Handles the received byte and calls the needed functions.\
**/
void Receive()
{
hasReceived = false;	// Clear the flag
switch(RXByte)		// Switch depending on command value received
{
	case MODE0:		// don't drive
		drivestate = 0;
		break;

	case MODE1:		// slow down
		if(duty_cycle >= 2)
		{
			duty_cycle--;
		}
		break;


	case MODE2:		// drive backward

		drivestate = 2;
		break;

	case MODE3:		// switch drive direction

		if (drivestate == 0){drivestate = 1;}
		else {drivestate = 0;}
		break;

	case MODE4:		// steer left
		P2OUT &= ~STEERRIGHT;
		P2OUT |= STEERLEFT;
		steeringmode = 1;
		break;

	case MODE5:		// center steering
		P2OUT &= ~STEERLEFT;
		P2OUT &= ~STEERRIGHT;
		steeringmode = 0;
		break;

	case MODE6:		// steer right
		P2OUT &= ~STEERLEFT;
		P2OUT |= STEERRIGHT;
		steeringmode = 2;
		break;

	case MODE7:		// speed up
		if(duty_cycle <= 198)
		{
			duty_cycle++;
		}
		break;

	case MODE8:		// drive forward

		drivestate = 1;
		break;

	case PWMMODE0:
		duty_cycle = 1;
		break;

	case PWMMODE1:
		duty_cycle = 40;
		break;

	case PWMMODE2:
		duty_cycle = 80;
		break;

	case PWMMODE3:
		duty_cycle = 120;
		break;

	case PWMMODE4:
		duty_cycle = 160;
		break;

	case PWMMODE5:
		duty_cycle = 199;
		break;


	case BLINKMODE0:
		blinkmode = 0;
		break;

	case BLINKMODE1:
		blinkmode = 1;
		break;	

	case BLINKMODE2:
		blinkmode = 2;
		break;

	default:;
   }
}
/**
* Transmits the value currently in TXByte. The function waits till it is
*   finished transmiting before it returns.
**/
void Transmit()
{
while(isReceiving);				// Wait for RX completion

 	TXByte |= 0x100;				// Add stop bit to TXByte (which is logical 1)
 	TXByte = TXByte << 1;				// Add start bit (which is logical 0)
 	BitCnt = 0xA;					// Load Bit counter, 8 bits + ST/SP

 	CCTL0 = OUT;					// TXD Idle as Mark
 	TACTL = TASSEL_2 + MC_2;			// SMCLK, continuous mode
 	CCR0 = TAR;					// Initialize compare register
 	CCR0 += Bit_time;				// Set time till first bit
 	CCTL0 =  CCIS0 + OUTMOD0 + CCIE;		// Set signal, intial value, enable interrupts
 	while ( CCTL0 & CCIE );				// Wait for previous TX completion
}




#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{

isReceiving = true;

P1IE &= ~RXD;			// Disable RXD interrupt
P1IFG &= ~RXD;			// Clear RXD IFG (interrupt flag)

 	TACTL = TASSEL_2 + MC_2;	// SMCLK, continuous mode
 	CCR0 = TAR;			// Initialize compare register
 	CCR0 += Bit_time_5;		// Set time till first bit
CCTL0 = OUTMOD1 + CCIE;		// Dissable TX and enable interrupts

RXByte = 0;			// Initialize RXByte
BitCnt = 0x9;			// Load Bit counter, 8 bits + ST

}

/**
* Timer interrupt routine. This handles transmiting and receiving bytes.
**/
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
if(!isReceiving)
{
	CCR0 += Bit_time;				// Add Offset to CCR0
	if ( BitCnt == 0)				// If all bits TXed
	{
 			TACTL = TASSEL_2;			// SMCLK, timer off (for power consumption)
		CCTL0 &= ~ CCIE ;			// Disable interrupt
	}
	else
	{
		CCTL0 |=  OUTMOD2;			// Set TX bit to 0
		if (TXByte & 0x01)
			CCTL0 &= ~ OUTMOD2;		// If it should be 1, set it to 1
		TXByte = TXByte >> 1;
		BitCnt --;
	}
}
else
{
	CCR0 += Bit_time;						// Add Offset to CCR0
	if ( BitCnt == 0)
	{
 			TACTL = TASSEL_2;					// SMCLK, timer off (for power consumption)
		CCTL0 &= ~ CCIE ;					// Disable interrupt

		isReceiving = false;

		P1IFG &= ~RXD;						// clear RXD IFG (interrupt flag)
		P1IE |= RXD;						// enabled RXD interrupt

		if ( (RXByte & 0x201) == 0x200)		// Validate the start and stop bits are correct
		{
			RXByte = RXByte >> 1;			// Remove start bit
			RXByte &= 0xFF;					// Remove stop bit
			hasReceived = true;
		}
 			__bic_SR_register_on_exit(CPUOFF);	// Enable CPU so the main while loop continues
	}
	else
	{
		if ( (P1IN & RXD) == RXD)			// If bit is set?
			RXByte |= 0x400;			// Set the value in the RXByte
		RXByte = RXByte >> 1;				// Shift the bits down
		BitCnt --;
	}
}
}

#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{

	++timer;
	if (timer == PERIOD) 
	{ 
		timer = 0;
		if (drivestate == 1)		// forward drive pwm
		{ 
			P2OUT |= BIT1;
		}
		else if (drivestate == 2)	// backward drive pwm
		{ 
			P2OUT |= BIT3;
		}  

	}
	if (timer == duty_cycle ) { P2OUT &= ~BIT1; P2OUT &= ~BIT3;}
	//end interrupt
}

void setShiftReg()			// Sends the values  of shiftbit[i] to the shiftregister
{

for (i = 0; i < 8; i++)
{
	if (shiftbit[i] == 1)
	{
		P1OUT |= SHIFTDATA;
	}
	else
	{
		P1OUT &= ~SHIFTDATA;
	}
	pulseShiftClock();
	P1OUT &= ~SHIFTDATA;	
}	
pulseShiftLatch();
}

void pulseShiftClock()		// pulse shiftregister clock pin
{
P2OUT |= SHIFTCLOCK;
P2OUT &= ~SHIFTCLOCK;
}

void pulseShiftLatch()		// pulse shiftregister latch pin
{
P2OUT |= SHIFTLATCH;
P2OUT &= ~SHIFTLATCH;
}

 

Hope that was helpful :)

 

Cheers!

 

MarkoeZ

Link to post
Share on other sites

Thanks :)

There are only a couple of people that recently received external connectors for the Pandora, and most only want it for A/V out. So me and another guy are currently trying to figure out how to enable the extra uarts, set voltage levels, etc. That discussion is here http://boards.openpandora.org/index.php ... d-pandora/ if anyone is interested. (i'm a linux noob as well, that does not really help things ; )

 

Cheers!

Link to post
Share on other sites

Well not much to post on the main project yet, mainly doing research. But since this is still a noobs introduction: I discovered about soundcard oscilloscopes yesterday night, and started experimenting with it this evening. Pretty nice stuff for (near) nothing :)

 

MarkoeZ MSP430 Launchpad Video's Part 9: PC Soundcard Oscilloscope for testing:

 

Cheers!

Link to post
Share on other sites

And yet another video. i think this one deserves a small intro:

 

Updated from last video, i attached a wire for steering left on the rc car (i fried steering right..) combined the code from the last video with the code from the serial leds, and behold: serial controlled RC car!

 

Eventually there will be at least 10 states: stop, forward, forward right, right. backward right... *SNIP* ...launch missile, trigger flametorch, whatever. ;)

 

Also reattached the leds to signal drive forward and reverse. It needs a resistor from the signal port to the transistors connected to the leds, otherwise there is not enough power left available to signal the RC car.

 

Video Here:

MarkoeZ MSP430 Launchpad Video's Part 11:RC Car controlled through PC Serial Loud Noise Warning!!

 

Next up: Sensors

Cheers!

Link to post
Share on other sites

Late evening video. Soldered connectors to the car and the testboard, showing in the first part. I used audio cables since i have them in all kinds of combinations, so easy extending/splitting/whatever. If i have more channels, i have white and yellow ready as well.

Big plus is, i can screw the board up on the car eventually and directly plug in, or keep it loose and just connect an extension wire while drive testing.

 

Second part is just for fun, the first drive tests :) (still using serial)

 

First test shows: lower the gear. Moving way too fast atm, and could use some more power to get over obstacles. Very funny, but not practical later on

 

And the video:

MarkoeZ MSP430 Launchpad Video's Part 12: Serial RC car, added connectors and first drive test!

 

Cheers!

Link to post
Share on other sites

ok, back again. Been testing a very cheap collision detection system, using only an IR Led and a Photodiode.

 

I started with some reading on this site to get some general info first:

http://www.societyofrobots.com/sensors.shtml (good site anyway,lots of explanations and tutorials on robotics, sensors, motor drive, etc.) .

 

Then i used the code from this site:

http://gushh.net/blog/msp430-launchpad-led-as-photodiode/

and started hacking away at that.

 

As the video shows, working pretty nice.

 

Also general update: The eventual project i have in mind will not use the rc car as base. I want 2 drive motors for the main back wheels, individually controllable for fast turning. But also wheel rotation sensors to make sure they travel the same distance and front wheel steering for fast travel forward. But already almost running out of pins, so going to need more (and/or different) MSP's, shift registers, boards, connectors and what more probably. Should be fun :)

 

Cheers!

Link to post
Share on other sites

Next step: I started work on the first implementation of a drive mechanic, combining the sensor and drive programs. Will be more refined, with better sensors, but just working toward something driving now.

 

Also have some ideas about how to build everything into the original porsche shell

 

 

And once again, tips and comments are greatly appreciated!

 

Cheers!

Link to post
Share on other sites

You've been doing great. Just chiming in to say "good job" and keep those video's coming. This serves as a nice project blog too.

I have one suggestion or comment. Are you PWM'ing the motors or just going high/low on the driver pins. With PWM you can get speed control. This will also be helpful when you do closed loop control using your sensors.

Link to post
Share on other sites

Thanks! I did some pwm tests already, but not in the video examples. I'm still figuring out how to arrange everything in the main drive program with loops/clocks/timers/interrupts/etc. Not an easy task the first time...

 

But a general question: I'm currently looking at ultrasonic range detectors, but there are 3 main versions as i see it. Serial, I2C, and direct pulse. Now which one would be most versatile? I like the i2c/serial ones, but would that mean i need 2 pins for the sensor, and then another 2 for pc/pandora communication? or can those use the same tx/rx pins and use commands to detect where the signal is coming from? (i'm a pretty capable c++ programmer, but serial com development is completely new to me)

Because the direct pulse one has just one pin for send pulse and receive echo. Quite efficient, but would mean more processing load for the msp probably?

 

And i decided to try and keep this first project a bit basic, and limited to one msp/launchpad, so have to be careful about the use of pins. The next project (for which im already gathering components and intelligence) will hopefully have an MSP430 dedicated to sensors, one for the motors, and one for critical stuff like emergency braking and communication from everything to the pandora.

 

Cheers!

Link to post
Share on other sites

I would suggest yo go for serial/I2C devices as they do the heavy lifting for you..otherwise you will have to note the time of pulse and the return pulse and use a the speed equation to get distance. There are analog rangefinders too, that will save you serial port pins as well as do the processing work.

Link to post
Share on other sites

Ah, thanks for the tip, that one seems ideal since it can also operate in serial mode for future projects.

 

Also general update: For the eventual robot project (the rc car is a warmup, in case it was not clear yet) i think i obtained 2 12v, 5 line, stepper motors with rotation sensor to drive the 2 main drive wheels. Planning to use shift registers for those so i don't have to use 5 pins of an msp per motor. But that way i would have full control over movement distance forward, backward, and rotation. Pretty neat.

Link to post
Share on other sites

This is a shy recommendation as I have not looked very closely at them so basically talking out of my bottom, but you could also look at LED drivers (MAX6957 I got recently). They probably won't do PWM (for microstepping), but otherwise, driven by I2C and loads of (relatively) high- and constant-current outputs. There are also some other tips on the URL above for alternatives.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...