Works on USB power. Fails when using VIN [SOLVED]

I tried powering my Spark core from an external 5V supply for the first time today, with hilarious results. When on USB power everything works fine. I can talk to my core and so on, and the LED is a breathing cyan colour. I am also flashing the blue LED on D7.
If I disconnect the USB cable and put 5V to VIN (pin 1) and 0V to GND (pin 2) it doesn’t work. Instead of the breathing cyan LED I get a breathing (not flashing) orange LED and the blue LED doesn’t flash at all. Nothing much works. If I do a “spark list” from the command line it reports my core is offline.
Why is this?
One thing I did consider (but haven’t tried yet) is that the code does open a connection to Serial (using Serial.begin) but from then on doesn’t actually bother to write to the serial port. Could it be that if you don’t actually have a USB connection between the core and a PC then the serial port won’t work at all and will actually cause the code to hang? I assumed it would let me open the port and carry on, but maybe not.

Your 5V supply might not be providing enough current.

1 Like

@RichardE Could you post your code? Are you waiting for the serial connect from the other side like the code below?

void setup()
{
    Serial.begin(9600);
    while (!Serial.available()) Spark.process();

    pinMode(LED, OUTPUT);
    ...
}

@RichardE, what sort of 5V power supply do you use?
Does it supply propper filtered 5V or only rectified 5V (aka pulsed DC)?

There’s quite a lot of code, but setup looks like this:

//
/* INITIALISATION CODE */
/
/
void setup() {
// Configure LED pin as output.
pinMode( LED, OUTPUT );
// Set initial state and update LED pin.
ledState = LOW;
digitalWrite( LED, ledState );
// Initialise the USB serial port used for debugging messages.
Serial.begin( 38400 );
// Wait for incoming serial data from computer.
// while( Serial.available() < 1 ) {
// do nothing
// }
// Serial.println( “Running!” );
// Create a digital output to turn RS485 transmitter on and off.
txEnable = new DigitalOut( D2 );
// Create a very low level serial port on the TX and RX pins for talking to local micros.
localMicroPort = new SerialPort( SerialPort::Port1 );
// Open port at a baud rate of 38400.
localMicroPort->Open( 38400 );
// Create a packet transmitter.
transmitter = new RS485PacketTransmitter( localMicroPort, txEnable );
// Initialise micros and create a scan list.
scanList = InitialiseMicros();
// Turn off all valve channels.
for( UInt8 v = 0; v < LVCVALVECHANNELCOUNT; ++v ) {
lvc.SetValveEnable( v, false );
}
// Set all valve demands to maximum.
for( UInt8 v = 0; v < LVCVALVECHANNELCOUNT; ++v ) {
lvc.SetValveDemand( v, (float)LVCMAXDEMAND );
}
// Set LVC to work with.
sparkFunctions.SetLVC( &lvc );
// Register spark functions.
Spark.function( “Set”, SparkSet );
Spark.function( “Reset”, SparkReset );
// Register spark variables.
ValveCurrents[ 0 ] = (char)0;
Spark.variable( “VC”, ValveCurrents, STRING );
OverCurrents[ 0 ] = (char)0;
Spark.variable( “OC”, OverCurrents, STRING );
// Do a reset.
SparkReset( “” );
// Prepare for first transmission.
storeRec = InitialiseTransmit( &scanListRec, &replyId );
// Transmit first packet in 1 second from now.
txTime = (long)millis() + 1000L;
// No bad replies yet.
badReplyCount = 0;
}

Note that the lines that wait for a character from the serial port are commented out. Only the serial.begin call remains.
The loop function looks like this:

//
/* CODE CALLED REPEATEDLY */
/
/
void loop() {
// Read the ms timer.
long now = (long)millis();
// If time to transmit the next packet to the LVC do so.
if( now - txTime >= 0L ) {
if( storeRec != NULL ) {
// Toggle LED.
ledState = ( ledState == LOW ) ? HIGH : LOW;
digitalWrite( LED, ledState );
UInt8 pktNum = scanListRec->PacketNumber;
LocalMicro *micro = storeRec->Micro;
UInt8 *downPacket = micro->GetDownPacket( pktNum );
// Serial.print( "\r\nTX " );
// Serial.println( downPacket[ 0 ], HEX );
// Disable interrupts.
// It seems that the millis() function continues to work even
// with interrupts disabled.
noInterrupts();
// Transmit next packet.
transmitter->TransmitPacket( downPacket, DOWNPACKETSIZE );
// Listen for reply.
bool gotReply = ReceiveReply();
// Enable interrupts.
interrupts();
// Do something with received reply.
if( gotReply ) {
// Get pointer to received packet.
UInt8 *packet = rxPacketProcessor.GetPacket();
// Calculate expected checksum.
UInt8 calcCS = LocalMicro::CalculateChecksum( packet, UPPACKETSIZE );
// If checksum matches the last byte in the packet then store it away
// and mark packet as valid.
if( calcCS == packet[ UPPACKETSIZE - 1 ] ) {
memcpy(
micro->GetUpPacket( pktNum ),
packet,
UPPACKETSIZE
);
micro->SetUpPacketValid( pktNum, true );
// Got a good reply so reset count of consecutive bad
// replies to zero.
badReplyCount = 0;
}
else {
// Bad checksum. Add one to count of bad replies.
BadReply();
}
}
else {
// Add one to count of bad replies.
BadReply();
}
}
// Prepare for next transmission.
storeRec = InitialiseTransmit( &scanListRec, &replyId );
// Transmit next packet some time later.
txTime += 200L;
// Regenerate reading buffers.
ReadingGenerator::GenerateValveCurrents( ValveCurrents, SPARKREADINGBUFFERSIZE, &lvc );
ReadingGenerator::GenerateOverCurrents( OverCurrents, SPARKREADINGBUFFERSIZE, &lvc );
}
}

Basically it sends a transmission and receives a reply every 200 ms, but otherwise doesn’t do that much.
As I say the code works fine from USB power. It starts right away. It doesn’t wait for anything on the USB serial port.

Kenneth, I think you may be right about the 5V supply. It’s only good for 40 mA. I suspect that may not be enough. Apologies I thought it could handle more than that. It’s actually a supply generated by the PCB I am communicating with.

You need about 10 times that current (more than 350mA) to run the TI part effectively!

Yes. My own fault.
However, just out of curiosity, if the Spark isn’t getting enough current to run, how does it manage to make the LED breathe orange? There must be some sort of program running to make it do that. I would have expected it to just sit there, held in reset.

The current is just enough to power the microcontroller but not the LEDs (although some would lit up dimly) or the WiFi module!