LinkSprite Camera with TTL Serial

It took like 2 minutes or so!

I’m hoping to play with a I2C version or SPI which is much faster snd should do the job well :slight_smile:

1 Like

Yeah, good idea. I couldn’t find a suitably priced I2C camera, but I used the Link Sprite one mentioned above on my Arduino Uno with similar results. 320x240 only took around 20 seconds from taking the picture to fully transferring to over USB to the PC though. How did you manage to implement the camera on the Spark Core? Did you disable the Wi-Fi capabilities or find a way to create/ utilise an alternative serial port?

Nope. All you need to do is to use Serial1 to connect to the camera and print via Serial which is the USB serial on the :spark: core:)

Thanks, Kenneth. I must admit I’m still struggling to get it working with the core. If I put the core into 'USB mode (with the pulsing blue LED) I can connect via cool term, however, in this mode it appears my code does not run. Then when I have it in usual mode (with the cya pulsing) I don’t seem to be able to make a connection over USB. Am I missing something obvious? Thanks again and sorry for the questions!

No worries :smile:

You don’t put it that mode. Blinking blue means Smart Config mode.

To use Serial, we just need Serial.begin() and the COM port will be opened

Take a look and try this:

gist.github.com/kennethlimcp/aeaf353fd40c8f25be17

Did it months back but it should work fine

Dugged this up recently and the camera still manages to take nice selfies! :smiley:

3 Likes

Hello! Urgently need help, I got the LinkSprite JPEG Color Camera TTL Interface - Infrared and been trying to connect to my spark core and ran the code that comes with the camera documentation from sparkfun but nothing works! Baddly need to have this work by tomorrow, anyone? Please help!

Opps i think i have deleted the code but sending some simple commands with Serial1 should make it work no?

Tried this:

int led1 = D0; 

int led2 = D7;

void setup() {
    pinMode(led1, OUTPUT);
    pinMode(led2, OUTPUT);

    Spark.function("sendData", sendData);

    Serial1.begin(9600);
}

void loop() {
    if(Serial1.available()){
        Serial1.write(Serial1.read());
    }
    else {
        digitalWrite(led1, HIGH);
        digitalWrite(led2, HIGH);
    
        delay(1000);
    
        digitalWrite(led1, LOW);
        digitalWrite(led2, LOW);
    
        delay(1000);
    }
}

int sendData(String command){
    Serial.print("INCOMING: ");
    Serial.println(command);

    Serial1.print("SPARK: ");
    Serial1.println(command);

    return 1;
}

but nothing comes out, also tried the code that comes with it but gave me library errors and the online software isn’t very friendly with importing libraries… also tried running it in command line but gave me this: spark serial monitor
I didn’t find any cores available via serial
No serial port identified

Could you point me in the right direction?

Hmm…

Serial is for serial via USB and Serial1 is for tx/rx to the camera. I can help later if i have time to write some code

1 Like

While Kenneth is whipping up some code, some things

  1. If you want to send commands to the camera via Serial1 you should not send SPARK: to start with, since the camera doesn’t like unknown commands.
  2. To help you with your serial monitor, we’d need to know what system you’re on and what serial monitor you’re using (is it the Particle Dev built-in monitor? Since you mentioned command line, I’m a bit puzzled about this).
    If you’re on Windows you might need to install the Particle drivers

As Kenneth pointed out, you might want to change this too

    if(Serial1.available())
    {
      // instead of this
      //Serial1.write(Serial1.read());
      // try
      while(Serial1.available())
      {
        Serial.write(Serial1.read());  // read RX (Serial1) and send to USB (Serial)
        Spark.process();
      }
    }

Not sure if this works:

/*
Test code to output an image via USB Serial @ 9600

1.) Linksprite TTL camera @ 38400
2.) Need to copy transferred content to HEXedit before saving as JPG

Updated on: 28 January 2015
*/


#define mySerial Serial1

SYSTEM_MODE(MANUAL);

byte ZERO = 0x00;
byte incomingbyte;
long int j=0,k=0,count=0,i=0x0000;
uint8_t MH,ML;
boolean EndFlag=0;
//File  myFile;

void SendResetCmd()
{
    mySerial.write(0x56);
    mySerial.write(ZERO);
    mySerial.write(0x26);
    mySerial.write(ZERO);
}

/*************************************/
//* Set ImageSize :
//* <1> 0x22 : 160*120
//* <2> 0x11 : 320*240
//* <3> 0x00 : 640*480
//* <4> 0x1D : 800*600
//* <5> 0x1C : 1024*768
//* <6> 0x1B : 1280*960
//* <7> 0x21 : 1600*1200
/************************************/
void SetImageSizeCmd(byte Size)
{
    mySerial.write(0x56);
    mySerial.write(ZERO);
    mySerial.write(0x54);
    mySerial.write(0x01);
    mySerial.write(Size);
}

/*************************************/
//* Set BaudRate :
//* <1>¡¡0xAE  :   9600
//* <2>¡¡0x2A  :   38400
//* <3>¡¡0x1C  :   57600
//* <4>¡¡0x0D  :   115200
//* <5>¡¡0xAE  :   128000
//* <6>¡¡0x56  :   256000
/*************************************/
void SetBaudRateCmd(byte baudrate)
{
    mySerial.write(0x56);
    mySerial.write(ZERO);
    mySerial.write(0x24);
    mySerial.write(0x03);
    mySerial.write(0x01);
    mySerial.write(baudrate);
}

void SendTakePhotoCmd()
{
    mySerial.write(0x56);
    mySerial.write(ZERO);
    mySerial.write(0x36);
    mySerial.write(0x01);
    mySerial.write(ZERO);
}

void SendReadDataCmd()
{
    MH=i/0x100;
    ML=i%0x100;
    mySerial.write(0x56);
    mySerial.write(ZERO);
    mySerial.write(0x32);
    mySerial.write(0x0c);
    mySerial.write(ZERO);
    mySerial.write(0x0a);
    mySerial.write(ZERO);
    mySerial.write(ZERO);
    mySerial.write(MH);
    mySerial.write(ML);
    mySerial.write(ZERO);
    mySerial.write(ZERO);
    mySerial.write(ZERO);
    mySerial.write(0x20);
    mySerial.write(ZERO);
    mySerial.write(0x0a);
    i+=0x20;
}

void StopTakePhotoCmd()
{
    mySerial.write(0x56);
    mySerial.write(ZERO);
    mySerial.write(0x36);
    mySerial.write(0x01);
    mySerial.write(0x03);
}

void setup()
{
    Serial.begin(921600);
    while (!Serial.available()); // wait for serial port to connect. Needed for Leonardo only


   // Serial.print("Initializing SD card...");
    // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
    // Note that even if it's not used as the CS pin, the hardware SS pin
    // (10 on most Arduino boards, 53 on the Mega) must be left as an output
    // or the SD library functions will not work.
    //pinMode(10, OUTPUT);
    // if (!SD.begin(4))
    // {
    //     Serial.println("initialization failed!");
    //     return;
    // }
    Serial.println("initialization done.");
    Serial.println("please wait ....");

    mySerial.begin(38400);
    delay(100);
    SendResetCmd();
    delay(2000);
//    SetBaudRateCmd(0x2A);
//    delay(500);
//    mySerial.begin(38400);
//    delay(100);
}

void loop()
{
    byte a[32];
    int ii;

    SendResetCmd();
    delay(2000);                            //Wait 2-3 second to send take picture command
    SendTakePhotoCmd();
    delay(1000);

    while(mySerial.available()>0)
    {
        incomingbyte=mySerial.read();
    }

   // myFile = SD.open("pic.jpg", FILE_WRITE); //The file name should not be too long

    while(!EndFlag)
    {
        j=0;
        k=0;
        count=0;
        //mySerial.flush();
        SendReadDataCmd();
        delay(20);
        while(mySerial.available()>0)
        {
            incomingbyte=mySerial.read();
            k++;
            delay(1); //250 for regular
            if((k>5)&&(j<32)&&(!EndFlag))
            {
                a[j]=incomingbyte;
                if((a[j-1]==0xFF)&&(a[j]==0xD9))     //tell if the picture is finished
                {
                    EndFlag=1;
                }
                j++;
                count++;
            }
        }

        for(j=0;j<count;j++)
        {
            if(a[j]<0x10)  Serial.print("0");
            Serial.print(a[j],HEX);           // observe the image through serial port
            Serial.print(" ");
        }

  //      for(ii=0; ii<count; ii++)
      //  myFile.write(a[ii]);
  //      Serial.println();
    }

    //myFile.close();
    Serial.print("Finished writing data to file");
    while(1);
}
1 Like

@kennethlimcp, you might want to put a timeout and a Spark.process() into the while(); in setup.
Otherwise the program will stay there, till you explicitly send data to the Core via USB-Serial.


Edit: Forget Spark.process(), since it’s SYSTEM_MODE(MANUAL) - realized after posting :blush:

That’s old copy-and-paste code :wink:

also, we are in MANUAL mode…

1 Like

I’m on Mac, and yes I am using the particle Build online, the code I’ve been trying to use is:

// This #include statement was automatically added by the Particle IDE.
#include "NewSoftSerial.h"

/* Linksprite */
 
//#include <NewSoftSerial.h>
 
byte incomingbyte;
NewSoftSerial mySerial(4,5);                     //Configure pin 4 and 5 as soft serial port
int a=0x0000,j=0,k=0,count=0;                    //Read Starting address       
uint8_t MH,ML;
boolean EndFlag=0;
 
void SendResetCmd();
void SendTakePhotoCmd();
void SendReadDataCmd();
void StopTakePhotoCmd();
 
void setup()
{ 
  Serial.begin(19200);
  mySerial.begin(38400);
}
 
void loop() 
{
     SendResetCmd();
     delay(4000);                               //After reset, wait 2-3 second to send take picture command
 
      SendTakePhotoCmd();
 
     while(mySerial.available()>0)
      {
        incomingbyte=mySerial.read();
 
      }   
      byte a[32];
 
      while(!EndFlag)
      {  
         j=0;
         k=0;
         count=0;
         SendReadDataCmd();
 
         delay(25);
          while(mySerial.available()>0)
          {
               incomingbyte=mySerial.read();
               k++;
               if((k>5)&&(j<32)&&(!EndFlag))
               {
               a[j]=incomingbyte;
               if((a[j-1]==0xFF)&&(a[j]==0xD9))      //Check if the picture is over
               EndFlag=1;                           
               j++;
	       count++;
               }
          }
 
          for(j=0;j<count;j++)
          {   if(a[j]<0x10)
              Serial.print("0");
              Serial.print(a[j],HEX);
              Serial.print(" ");
          }                                       //Send jpeg picture over the serial port
          Serial.println();
      }      
     while(1);
}
 
//Send Reset command
void SendResetCmd()
{
      mySerial.print(0x56, BYTE);
      mySerial.print(0x00, BYTE);
      mySerial.print(0x26, BYTE);
      mySerial.print(0x00, BYTE);
}
 
//Send take picture command
void SendTakePhotoCmd()
{
      mySerial.print(0x56, BYTE);
      mySerial.print(0x00, BYTE);
      mySerial.print(0x36, BYTE);
      mySerial.print(0x01, BYTE);
      mySerial.print(0x00, BYTE);  
}
 
//Read data
void SendReadDataCmd()
{
      MH=a/0x100;
      ML=a%0x100;
      mySerial.print(0x56, BYTE);
      mySerial.print(0x00, BYTE);
      mySerial.print(0x32, BYTE);
      mySerial.print(0x0c, BYTE);
      mySerial.print(0x00, BYTE); 
      mySerial.print(0x0a, BYTE);
      mySerial.print(0x00, BYTE);
      mySerial.print(0x00, BYTE);
      mySerial.print(MH, BYTE);
      mySerial.print(ML, BYTE);   
      mySerial.print(0x00, BYTE);
      mySerial.print(0x00, BYTE);
      mySerial.print(0x00, BYTE);
      mySerial.print(0x20, BYTE);
      mySerial.print(0x00, BYTE);  
      mySerial.print(0x0a, BYTE);
      a+=0x20;                            //address increases 32,set according to buffer size
}
 
void StopTakePhotoCmd()
{
      mySerial.print(0x56, BYTE);
      mySerial.print(0x00, BYTE);
      mySerial.print(0x36, BYTE);
      mySerial.print(0x01, BYTE);
      mySerial.print(0x03, BYTE);        
}

I keep getting this errors:

In file included from ../inc/spark_wiring.h:29:0,
from ../inc/application.h:29,
from communication.cpp:2:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
communication.cpp:2:27: fatal error: NewSoftSerial.h: No such file or directory
#include "application.h"
^
compilation terminated.
make: *** [communication.o] Error 1 

and still can’t see the serial port or something where I can actually verify if the camera is sending/recieving any data, am I missing something obvious? This is taking me to long :frowning:

Is there a special reason to use NewSoftSerial?

Have you attached the cam to D4/D5?

Hi @KarinaMendez

@ScruffR is right on here: the Particle Core has two hardware serial ports available so you don’t need the new soft serial library, and in fact, I am not sure if that library works on Spark due to interrupt differences.

2 Likes

No, I just left the code the way I dowloaded it from the sprakfun page, and about the pins:

(From camera)
red= RX
brown = TX
purple = GND
ray = VIN

Then you have to remove NewSoftSerial and use Serial1 instead, just as @kennethlimcp has got in his sample.
You may also connect RX of cam to TX of Core and vice versa.