Arduino SoftwareSerial connection with LinkSprite Jpeg Camera - arduino

So we're having trouble connecting the Arduino Uno to the LinkSprite camera, we've been using the LinkSprite sample code with a few print statements added
#include < SoftwareSerial.h >
/* Linksprite */
byte incomingbyte;
SoftwareSerial mySerial(4, 5); //Configure pin 4 and 5 as soft serial port
long 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(38400);
mySerial.begin(38400);
Serial.print("Serial began\n");
}
void loop() {
SendResetCmd();
Serial.print("Reset Command Sent\n");
Serial.print(mySerial.available());
Serial.print("\n");
while (mySerial.available() > 0) {
incomingbyte = mySerial.read();
Serial.print(incomingbyte, HEX);
} //After reset, wait 2-3 second to send take picture command
Serial.print("Delay Ended\n");
SendTakePhotoCmd();
Serial.print("Take Photo Command Sent\n");
while (mySerial.available() > 0) {
Serial.print("Checking Available Bytes\n");
incomingbyte = mySerial.read();
}
byte a[32];
Serial.print("Byte array intialized\n");
while (!EndFlag) {
Serial.print("Entering While loop\n");
j = 0;
k = 0;
count = 0;
SendReadDataCmd();
Serial.print("Read Command Sent\n");
delay(250);
Serial.print("Delay Ended\n");
Serial.print(mySerial.available());
Serial.print("\n");
while (mySerial.available() > 0) {
incomingbyte = mySerial.read();
Serial.print("Incoming Byte Read\n");
k++;
if ((k > 5) && (j < 32) && (!EndFlag)) {
Serial.print("Byte Added to Array\n");
a[j] = incomingbyte;
if ((a[j - 1] == 0xFF) && (a[j] == 0xD9)) { //Check if the picture is over
Serial.print("End Flag");
EndFlag = 1;
}
j++;
count++;
}
}
for (j = 0; j < count; j++) {
if (a[j] < 0x10)
Serial.print("0");
Serial.print("Picture Printing\n");
Serial.print(a[j], HEX);
Serial.print(" ");
} //Send jpeg picture over the serial port
Serial.println();
delay(10000);
}
Serial.print("Picture Complete");
while (1);
}
//Send Reset command
void SendResetCmd() {
mySerial.write(0x56);
mySerial.write(byte(0x00));
mySerial.write(0x26);
mySerial.write(byte(0x00));
}
//void SetImageSizeCmd()
//{
//mySerial.write(0x56);
//mySerial.write(byte(0x00));
//mySerial.write(0x31);
//mySerial.write(0x05);
//mySerial.write(0x04);
//mySerial.write(0x01);
//mySerial.write(byte(0x00));
//mySerial.write(0x19);
//mySerial.write(0x22);
//}
//void SetBaudRateCmd()
//{
//mySerial.write(0x56);
//mySerial.write(byte(0x00));
//mySerial.write(0x24);
//mySerial.write(0x03);
//mySerial.write(0x01);
//mySerial.write(0xAE);
//mySerial.write(0xC8);
//
//}
//Send take picture command
void SendTakePhotoCmd() {
mySerial.write(0x56);
mySerial.write(byte(0x00));
mySerial.write(0x36);
mySerial.write(0x01);
mySerial.write(byte(0x00));
}
//Read data
void SendReadDataCmd() {
MH = a / 0x100;
ML = a % 0x100;
mySerial.write(0x56);
mySerial.write(byte(0x00));
mySerial.write(0x32);
mySerial.write(0x0c);
mySerial.write(byte(0x00));
mySerial.write(0x0a);
mySerial.write(byte(0x00));
mySerial.write(byte(0x00));
mySerial.write(MH);
mySerial.write(ML);
mySerial.write(byte(0x00));
mySerial.write(byte(0x00));
mySerial.write(byte(0x00));
mySerial.write(0x20);
mySerial.write(byte(0x00));
mySerial.write(0x0a);
a += 0x20; //address increases 32£¬set according to buffer size
}
void StopTakePhotoCmd() {
mySerial.write(0x56);
mySerial.write(byte(0x00));
mySerial.write(0x36);
mySerial.write(0x01);
mySerial.write(0x03);
}
`
The code basically sends a take picture command to the camera and then reads the HEX values that the camera sends and saves the values in an array. We know the camera works because we tested it on another device.
The problem initially was, the values that we were getting from the camera aren't correct. The EndFlag in the while loop is never toggled because the HEX values that indicate the end of a JPEG values (FF and D9) are never read so it never breaks from the while loop. Now, the terminal doesn't print anything until the camera is disconnected, then all the values seem to get flushed to the screen and the command mySerial.available() returns 0 meaning that there is nothing in the serial read buffer.

I compared your code with the example sketch provided from the manufacturer and figured out that your initialization procedure differs from the original. In the official sample code they first connect to the camera on 115200 serial baudrate, tells camera to change it's baudrate to 38400 and then they connect to camera again but with different speed - 38400 baud.
In your code I see that you are connecting on 38400 baud speed in the beginning. However, the camera is operating at a different speed and this explains why you get garbage instead of valid data. I recommend that you perform the correct initialization procedure, as described in the example:
void setup()
{
Serial.begin(38400);
mySerial.begin(115200);
delay(100);
SendResetCmd();
delay(2000);
SetBaudRateCmd(0x2A);
delay(500);
mySerial.begin(38400);
delay(100);
Serial.println("initialization done.");
}
Also, uncomment SetBaudRateCmd() function as it's used in the initialization procedure.

Related

I could not make IRsend from the IRremote library to work

Hello i am using an arduino mkr1000 so send and IR signal using the IRremote library for mkr1000 IRremote library. I am having problems with IRsend.
First i used the IRdump example to get the data from my remote button. When i finished this i tried the IRsend example but it seems to be not working.
I temporarily replaced with a ordinary LED to show if it is really blinking, but it is not. I have tested the both the ordinary LED and IR LED that they worked.
I also think that i have wired the LED correctly according to the example
PIN 3 -> LED -> Resistor -> Ground
My circuit was further confirmed correct when i upload a sketch that makes it blink.
Basically i am trying to send a NEC 32bit signal, 0x2FD807F
but i guess they were not able to finish the library of send for mkr1000???
in this post a comment was made with a code but did not really have any detail on how to use it.
here is where i am currently at
int IR_S = 3;
void setup()
{
pinMode(IR_S,OUTPUT);
}
void loop() {
IR_Sendcode(0x2FD807F);
delay(1000);
}
void IR_Send38KHZ(int x,int bit) //Generate 38KHZ IR pulse
{
for(int i=0;i<x;i++)//15=386US
{
if(bit==1)
{
digitalWrite(IR_S,1);
delayMicroseconds(9);
digitalWrite(IR_S,0);
delayMicroseconds(9);
}
else
{
digitalWrite(IR_S,0);
delayMicroseconds(20);
}
}
}
void IR_Sendcode(uint8_t data) // Send the data
{
for(int i=0;i<8;i++)
{
if((data&0x01)==0x01)
{
IR_Send38KHZ(23,1);
IR_Send38KHZ(64,0);
}
else
{
IR_Send38KHZ(23,1);
IR_Send38KHZ(21,0);
}
data=data>>1;
}
}
I while i was waiting for replies i created my own code. I have finished and tested it. It should theoretically work on any arduino.
/*
This is a code for NEC Infrared Transmission Protocol Transmitter
NEC specifications are
~ Carrier Frequency is 38kHz
* Logical '0' – a 562.5µs pulse burst followed by a 562.5µs space, with a total transmit time of 1.125ms
* Logical '1' – a 562.5µs pulse burst followed by a 1.6875ms space, with a total transmit time of 2.25ms
- a 9ms leading pulse burst (16 times the pulse burst length used for a logical data bit)
- a 4.5ms space
- the 8-bit address for the receiving device
- the 8-bit logical inverse of the address
- the 8-bit command
- the 8-bit logical inverse of the command
- a final 562.5µs pulse burst to signify the end of message transmission.
Example,
If the code recieved from the data dump from the IRremote library is 0x2FD807F
-0x02 is address
-0xFD is the inverse address
-0x80 is the command
-0x7F is the inverse command
THIS PROGRAM IS A BLOCKING PROGRAM
*/
#define IR 3
#define CarrierFreqInterval 11
void setup() {
pinMode(IR, OUTPUT);
digitalWrite(IR, LOW);
}
void loop() {
// unsigned long start = micros();
transmit(0x02FD807F);
// unsigned long ends = micros();
// unsigned long delta = ends - start;
// Serial.println(delta);
delay(500);
}
void transmit(uint32_t data) {
//Function for transmiting the data
uint32_t bitcount = 0x80000000;
// 9ms pulse burst
for (int i = 0; i < 355; i++) {
digitalWrite(IR, HIGH);
delayMicroseconds(CarrierFreqInterval);
digitalWrite(IR, LOW);
delayMicroseconds(CarrierFreqInterval);
}
// 4.5ms space
delayMicroseconds(4500);
//8bit address,adress inverse,command,command inverse
while ( bitcount != 0b0) {
if ((data & bitcount) == bitcount) {
pulseHIGH();
}
else {
pulseLOW();
}
bitcount = bitcount >> 1;
}
//final pulse burst
for (int i = 0; i < 21; i++) {
digitalWrite(IR, HIGH);
delayMicroseconds(CarrierFreqInterval);
digitalWrite(IR, LOW);
delayMicroseconds(CarrierFreqInterval);
}
}
void pulseHIGH() {
// Pulse 38KHz good for a LOGIC '1'
for (int i = 0; i < 21; i++) {
digitalWrite(IR, HIGH);
delayMicroseconds(CarrierFreqInterval);
digitalWrite(IR, LOW);
delayMicroseconds(CarrierFreqInterval);
}
delay(1);
delayMicroseconds(687.5);
}
void pulseLOW() {
// Pulse 38KHz good for a LOGIC '0'
for (int i = 0; i < 21; i++) {
digitalWrite(IR, HIGH);
delayMicroseconds(CarrierFreqInterval);
digitalWrite(IR, LOW);
delayMicroseconds(CarrierFreqInterval);
}
delayMicroseconds(562.5);
}

Can I temporarily disable Arduino Serial data receive?

I am working on a project and I encountered some problems.
I am using a DHT11 temperature sensor, an Arduino Uno and a TFT LCD display 2.2-inch model ITDB02-2.2.
What I want my project to do is to use 2 functioning modes for the sensor that I can select from the keyboard at the beginning of the program(one which is normal and one which will be used on special occasions)(so I need serial communication).
I noticed that the screen does not function if I start a serial communication at any rate so I used Arduino Serial.begin(9600) and Serial.end() for the mode selecting part of the program.
THE PROBLEM: My Arduino is still sending data through serial port even if I ended the serial communication and is looking like this:
I found out that Serial.end() function does not shut off serial communication but just the rate of communication. I am curious if you have any idea that I can use in order to get rid of the extra data, to neglect it before the computer receives it.
I`m stuck. I thought that interruptions would be a solution but they are not as far as I researched on the internet.
My ARDUINO CODE:
#include <SimpleDHT.h>
#include <UTFT.h>
UTFT myGLCD(ITDB22,A5,A4,A3,A2);
SimpleDHT11 dht11;
// Declare which fonts we will be using
extern uint8_t BigFont[];
//dht sensor data pin
int dataPinSensor1 = 12;
char mode;
int del;
void setup()
{
Serial.begin(9600);
Serial.print("Select functioning mode");
mode=SensorModeSelect(mode);
Serial.end();
pinMode(12, INPUT);
}
void loop()
{
if(mode=='1') {
FirstFuncMode(dataPinSensor1);
}
if(mode=='2') {
SecondFuncMode(dataPinSensor1,del);
}
delay(10);
}
char SensorModeSelect(char in)
{
char mode='0';
while(mode=='0') {
if(Serial.available() > 0) {
mode=Serial.read();
}
}
if (mode == '1') {
Serial.print("\nMOD1 SELECTED: press t key to aquire data \n");
}
if (mode == '2') {
Serial.print("\nMOD2 SELECTED: press q if you want to quit auto mode \n");
Serial.print("Select the data aquisition period(not smaller than 1 second) \n");
}
return mode;
}
int DataAqPeriod()
{
int del=0;
while(del==0) {
while(Serial.available() > 0) {
//Get char and convert to int
char a = Serial.read();
int c = a-48;
del *= 10;
del += c;
delay(10);
}
}
del*=1000;
return del;
}
void FirstFuncMode(int dataPinSensor1)
{
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
bool DispCond=false;
Serial.begin(9600);
delay(1500);
if (Serial.read() == 't' ) {
DispCond=true;
//read temperature and compare it with an error value
if((err = dht11.read(dataPinSensor1, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("unreliable measurement or unselected functioning mode");
}
byte f = temperature * 1.8 + 32;
Serial.print((int)temperature);
Serial.print(" *C, ");
Serial.print((int)f);
Serial.print(" *F, ");
Serial.print((int)humidity);
Serial.println(" H humidity");
delay(1500);
}
Serial.end();
if(DispCond==true) {
//Setup the LCD
myGLCD.InitLCD();
myGLCD.setFont(BigFont);
//print value on LCD
displayNoInit((int)temperature,(int)humidity);
}
}
void SecondFuncMode(int dataPinSensor1,int del)
{
bool q=false;
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
Serial.begin(9600);
del=DataAqPeriod();
Serial.end();
//Setup the LCD
myGLCD.InitLCD();
myGLCD.setFont(BigFont);
while(q==false) {
Serial.begin(9600);
//read temperature and compare it with an error value
if((err = dht11.read(dataPinSensor1, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("unreliable measurement or unselected functioning mode \n");
}
float f = temperature * 1.8 + 32;
Serial.print((int)temperature);
Serial.print(" *C, ");
Serial.print((int)f);
Serial.print(" *F, ");
Serial.print((int)humidity);
Serial.println(" H humidity");
delay(del);
if(Serial.read() == 'q')
q=true;
Serial.end();
displayNoInit((int)temperature,(int)humidity);
delay(10);
}
}
void displayNoInit(int temperature,int humidity)
{
//effective data display
myGLCD.clrScr();
myGLCD.setColor(255, 255, 0);
myGLCD.setBackColor(10,10,10);
myGLCD.print(" Temperature ", CENTER, 10);
myGLCD.setColor(254, 254, 254);
myGLCD.printNumI(temperature, CENTER, 45);
myGLCD.setColor(255, 255, 0);
myGLCD.print("C ", RIGHT, 45);
myGLCD.print("Relative Hum.", CENTER, 90);
myGLCD.setColor(204, 245, 250);
myGLCD.printNumI(humidity, CENTER, 120);
myGLCD.print("%", RIGHT, 120);
}
You are correct in the definition that Serial.end() does not disable the serial monitor, only the interrupts. After calling Serial.end() you can disable the serial monitor like so.
#include <avr/io.h>
// Save status register, disable interrupts
uint8_t oldSREG = SREG;
cli();
// Disable TX and RX
cbi(UCSRB, RXEN);
cbi(UCSRB, TXEN);
// Disable RX ISR
cbi(UCSRB, RXCIE);
// Flush the internal buffer
Serial.flush();
// Restore status register
SREG = oldSREG;

Making a Game With Arduino and Processing

I am trying to form a two player game which requires an audio reflex to a visual. by using littebits sound trigger for sound input and littbits arduino to connect it to the computer. But I am new to this and don't know how to connect arduino to processing and use the input from sound trigger to effect the score when a black square appears.
here is my code in processing and a sample arduino code I have taken from littlebits website and tried to modify a little.
thanks in advance!
float dice;
int playerOne = 0; //player 1 score (left paddle)
int playerTwo = 0; //player 2 score (right paddle)
boolean oneWins = false;
boolean twoWins = false;
void setup(){
size(500, 500);
smooth();
noStroke();
frameRate(2.5);
}
void draw() {
background(255);
showGUI();
dice = random(0, 3);
if (dice < 1.000001 && dice > 0.1){
fill ((0), (255), (0));
ellipse (250,250,100,100);
} else if (dice < 2.000001 && dice > 1.000001){
rectMode(RADIUS);
fill ((255), (0), (0));
rect (250,250,50,50);
} else if (dice < 3.000000 && dice > 1.000000){
rectMode(RADIUS);
fill ((0), (0), (255));
rect (250,250,50,50);
} else if (dice < 0.1){
rectMode(RADIUS);
fill(0);
rect(250,250,50,50);
}
}
----------arduino------
void setup() {
Serial.begin(9600); //Establish rate of Serial communication
establishContact(); //See function below
}
void loop() {
if (Serial.available() > 0) {
int inByte = Serial.read();
int leftTrigger = analogRead(A0);
Serial.print(leftTrigger, DEC);
Serial.print(",");
int rightTrigger = analogRead(A1);
Serial.println(rightTrigger, DEC);
}
}
void establishContact() {
while (Serial.available() <= 0) {
Serial.println("hello");
delay(300);
}
}
You need two pieces of code for this to work: one on the Arduino that sends commands, and one for Processing to receive and parse those commands.
I haven't used the littlebits modules, but here's a button example from this very detailed tutorial.
Arduino code:
int switchPin = 4; // switch connected to pin 4
void setup() {
pinMode(switchPin, INPUT); // set pin 0 as an input
Serial.begin(9600); // start serial communication at 9600bps
}
void loop() {
if (digitalRead(switchPin) == HIGH) { // if switch is ON,
Serial.print(1, BYTE); // send 1 to Processing
} else { // if the switch is not ON,
Serial.print(0, BYTE); // send 0 to Processing
}
delay(100); // wait 100 milliseconds
}
And the matching Processing code:
import processing.serial.*;
Serial port; // create object from Serial class
int val; // data received from the serial port
void setup() {
size(200, 200);
frameRate(10);
// open the port that the board is connected to
// and use the same speed (9600bps)
port = new Serial(this, 9600);
}
void draw() {
if (0 < port.available()) { // if data is available,
val = port.read(); // read it and store it in val
}
background(255); // set background to white
if (val == 0) { // if the serial value is 0,
fill(0); // set fill to black
} else { // if the serial value is not 0,
fill(204); // set fill to light gray
}
rect(50, 50, 100, 100);
}
Notice that the Arduino sends a value that Processing looks for and interprets. You can also look at the PhysicalPixel example from the Arduino IDE for an example on sending data from Processing to Arduino.

ASCII reading with arduino

This is my first post, I know this theme could be very simple or obvious but I can't figure out how to solve it.
I have a capacitance meter from jyetech wiuch claims to have a 8-N-1 serial output, here is the link to the manual. I just want to read the output with my Arduino Uno, can anyone help me? Here is the code I have done, I'm getting some real data but also some strange characters.
#include <stdio.h>
void setup() {
Serial.begin(38400);
Serial.println("OK");
}
char command[1024];
char commandBuffer[128];
int commandBufferSize = 0;
void readCommandBuffer(int bytesToRead) {
int i = 0;
char c = 0;
while (i < 128 && (i < bytesToRead || bytesToRead <= 0)) {
while (!Serial.available())
;
c = Serial.read();
if (c == '\r' || c == '\n') {
break;
}
commandBuffer[i] = c;
i++;
}
commandBufferSize = i;
}
void readCommand() {
command[0] = '\0';
readCommandBuffer(0);
if (strncmp(commandBuffer, "RCV", 3) == 0) {
commandBuffer[commandBufferSize] = '\0';
int expectedSize = atoi(commandBuffer + 4);
if (expectedSize <= 0 || expectedSize > 1024) {
return;
}
Serial.println("RDY");
int bytesRead = 0;
while (bytesRead < expectedSize) {
readCommandBuffer(expectedSize - bytesRead);
memcpy(command + bytesRead, commandBuffer, commandBufferSize);
bytesRead += commandBufferSize;
Serial.print("ACK ");
Serial.println(commandBufferSize);
}
command[bytesRead] = '\0';
} else {
memcpy(command, commandBuffer, commandBufferSize);
command[commandBufferSize] = '\0';
}
}
void loop() {
if (Serial.available()) {
readCommand();
// "command" now contains the full command
Serial.println(command);
}}
You have to use two serial ports, one to talk to the PC (the usual Serial object), and the other to talk to the instrument.
If you have an Arduino UNO, which has only one hardware serial port, you have to use the software serial library. Mega boards have instead 4 hardware serial ports, which are available through the bulit-in objects Serial1, Serial2, etc.
BTW, just noticed a very similar question was asked awhile ago:
Serial Data communication Arduino

xbee pro s2b receiving random data

I have a trouble with xbee s2b.
I try to receive two joystick values using only xbee placed on sparkfun regulated board (Coordinator API) and process these data on Arduino Uno connected to other xbee s2b placed on explorer board.(Router API). I configured xbees using X-CTU properly and I adjusted DIO0 and DIO1 to ADC[2] on Router Xbee. There is no problem when working with one joystick. But when I try to receive two joystick values at the same time, they are not working correctly. When I look the incoming data on serial monitor, I see;
https://lh3.googleusercontent.com/-20vjr0EchsQ/VqyZXgq84VI/AAAAAAAAA_0/WhEtoOU61vA/s1280-Ic42/Screenshot_3.jpg
My Arduino code is:
int packet[32];
void setup()
{
Serial.begin(9600);
}
void loop(){
if (Serial.available() > 0) {
if (Serial.read() == 0x7E) {
packet[0] = 0x7E; //start delimiter
packet[1] = readByte(); //MSB1
packet[2] = readByte(); //MSB2
int dataLength = (packet[1] << 8) | packet[2]; //between the length and the checksum
printPacket(dataLength+4);
Serial.println("");
}
}
delay(1000);
}
void printPacket(int k) {
for(int i=0; i < k; i++) {
Serial.print(packet, HEX);
Serial.print(" ");
delay(1000);
}
}
int readByte() {
while (true) {
if (Serial.available() > 0) {
return Serial.read();
}
}
}
What is the point I missed? Can you help me about this issue. Thank you in advance.
The delay(1000) statements may be causing you to lose characters from your serial buffer, and might not be necessary.
The code you shared appears incomplete. Where are you reading the dataLength bytes of the packet? How does printPacket() print the bytes?
Your inbound packet buffer should be larger -- I think the XBee S2B can have network payloads of up to 255 characters, in addition to the frame header and checksum.
You've created a blocking readByte() call, which isn't good program design. Consider something like this instead:
unsigned char packet[300];
int packet_index = 0;
int packet_length;
void loop() {
while (Serial.available() > 0) {
packet[packet_index++] = Serial.read();
if (packet_index == 3) {
packet_length = (packet[1] << 8) | packet[2];
}
if (packet_index > 2 && packet_index == packet_length) {
print_packet();
packet_index = 0;
}
}
}
void print_packet() {
int i;
for (i = 0; i < packet_length; ++i) {
Serial.print(packet[i], HEX);
Serial.print(" ");
}
Serial.println("");
}
If you have too much data to print and you're overflowing your outbound serial buffer, try increasing the speed of the console's serial port to 115200bps. Or print the bytes as you receive them instead of waiting until the packet is complete.

Resources