I am sending 2 bytes from Processing to Arduino. These bytes are then stored in two values on the Arduino side, and then sent to a function that will then display them on a 7 segment 4 digit display.
The numbers are displayed fine! Yes, until about 5 seconds. I recorded it in slow motion.
9561 runs for about 5 seconds,
then a flash of 6100 very shortly,
and then 6195 very shortly
then it returns to 9561 for about 5 seconds again.
This can be changed slightly by altering the time each number is on the display, and I try to keep it below 4.
Anyways then changing the speeds on both programs also alters it, but I can't seem to get it right. Do I have to sync the programs through altering the speeds or is there a way to sync the numbers? I read into serialEvent() but not sure how to incorporate it into my project.
Here's my code below for the PROCESSING
void setup()
{
myPort = new Serial(this, Serial.list()[0], 9600);
}
void draw() {
seg[0] = 9;
seg[1] = 5;
seg[2] = 6;
seg[3] = 1;
int x = (seg[pos+1] & 0x000f)<<4|(seg[pos]) & 0x000f; //3210
int x2 = (seg[pos+3] & 0x000f)<<4|(seg[pos+2] & 0x000f);
myPort.write(x);
myPort.write(x2);
//0123
int disp1 = x;
int disp2 = (x & 0x00f0)>>4;
int disp3 = (x2 & 0x000f);
int disp4 = (x2 & 0x00f0)>>4;
//0123
print(disp1, '\n', disp2, '\n', disp3, '\n', disp4, '\n', '\n');
}
And ARDUINO
void setup() {
pinMode(GND1, OUTPUT);
pinMode(GND2, OUTPUT);
pinMode(GND3, OUTPUT);
pinMode(GND4, OUTPUT);
pinMode(aPin, OUTPUT);
pinMode(bPin, OUTPUT);
pinMode(cPin, OUTPUT);
pinMode(dPin, OUTPUT);
pinMode(ePin, OUTPUT);
pinMode(fPin, OUTPUT);
pinMode(gPin, OUTPUT);
pinMode(light, OUTPUT);
Serial.begin(9600);
}
void digitdisplay(byte x,byte x2)
{
//unsigned char tn = int (num/1000);
//if (tn>10)
//{
// tn = tn - 10;
//}
//
//unsigned char hn = int (num/100)%10;
//unsigned char tenn = int (num/10)%10;
//unsigned char on = int (num%10);
int disp[4];
disp[0] = ( x & 0x000f);
disp[1] = ( x & 0x00f0)>>4;
disp[2] = ( x2 & 0x000f);
disp[3] = ( x2 & 0x00f0)>>4;
numberselect(disp[0]);
digitselect(1);
delay(t);
numberselect(disp[1]);
digitselect(2);
delay(t);
numberselect(disp[2]);
digitselect(3);
delay(t);
numberselect(disp[3]);
digitselect(4);
delay(t);
}
void loop()
{
int x,x2;
if (Serial.available()>0)
{ // If data is available to read,
x=Serial.read();
x2=Serial.read();
}
//shiftlight(maxrange);
digitdisplay(x,x2);
}
Related
I am using the ESP8266 Wi-Fi shield to connect Arduino to the cayenne server. However once connect the chip to the access point it will heat up and sometimes will lagging. After that, it shows some message but the Cayenne server didn't connect to the Arduino. Every widget can not be operated (No response when clicking a button, temperature value unchanged, etc.). Can anyone solve this issue? It is important for my course work. I am using Arduino Uno and ESP8266 ESP-01 chip. We have tried different styles of code to upload data to cayenne server but they didn't work(Below include 3 versions)
Finale 1 Version(Cayenne out) :
#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP8266Shield.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <virtuabotixRTC.h>
//Real+Virtual
#define LED_PIN 5
#define temp_sensor 4
#define EspSerial Serial
//Virtual
#define Power_sensor 9
#define DayPower 10
#define MonthPower 11
#define LED_PWM 12
//SSID
char ssid[] = "TP-LINK_MWNg";
char password[] = "mwngpass";
char username[] = "743674368676328742somenumbers";
char mqtt_password[] = "743674368676328742somenumbers";
char client_id[] = "743674368676328742somenumbers";
ESP8266 wifi(&EspSerial);
//Temperature setup
OneWire oneWire(4);
DallasTemperature sensors(&oneWire);
//Power sensor
const int analogInPin = A0;
int sensorValue = 0; // value read from the pot
float MAXValue = 0; // value output to the PWM (analog out)
float Power = 0;
int PWM = 0;
//Time
int curSec = 0;
int curMin = 0;
int curHour = 0;
int curDay = 0;
virtuabotixRTC myRTC(6, 7, 8);
unsigned PowerInDay = 0;
unsigned PowerInMonth = 0;
void setup() {
// put your setup code here, to run once:
sensors.begin();
EspSerial.begin(115200);
delay(10);
Cayenne.begin(username, mqtt_password, client_id, wifi, ssid, password);
pinMode(LED_PIN, OUTPUT);
analogWrite(LED_PIN, PWM);
curSec = myRTC.seconds;
curMin = myRTC.minutes;
curHour = myRTC.hours;
curDay = myRTC.dayofmonth;
//test
}
void loop() {
Cayenne.loop();
myRTC.updateTime();
if ( curSec != myRTC.seconds ) {
PowerInDay += Power;
curSec = myRTC.seconds;
}
if (curDay != myRTC.dayofmonth) {
PowerInMonth += PowerInDay;
PowerInDay = 0;
curDay = myRTC.dayofmonth;
}
if (curDay > myRTC.dayofmonth) {
PowerInMonth = 0;
}
Serial.print(myRTC.dayofmonth);
Serial.print('/');
Serial.print(myRTC.month);
Serial.print('/');
Serial.print(myRTC.year);
Serial.print('/');
Serial.print(' ');
Serial.print(myRTC.hours);
Serial.print(':');
Serial.print(myRTC.minutes);
Serial.print(':');
Serial.print(myRTC.seconds);
Serial.print('\n');
Serial.print(PowerInDay);
Serial.print(' ');
Serial.print(PowerInMonth);
Serial.print('\n');
}
CAYENNE_OUT(temp_sensor)
{
sensors.requestTemperatures();
Cayenne.celsiusWrite(temp_sensor, sensors.getTempCByIndex(0));
}
CAYENNE_OUT(Power_sensor)
{
sensorValue = analogRead(analogInPin);
// map it to the range of the analog out:
if (sensorValue > 0)
MAXValue = sensorValue * 0.00007307;
Power = MAXValue * ((float)PWM / (float)255) * 3.3 * ((float)PWM / (float)255);
// change the analog out value:/
// print the results to the serial monitor:
Serial.print("sensor = ");
Serial.print(sensorValue); //RAW value from analog read :)
Serial.print("\t output = ");
Serial.println(MAXValue * ((float)PWM / (float)255), 3); //Output the current
Serial.print("Power =");
Serial.println(Power, 3);
// wait 2 milliseconds before the next loop
// for the analog-to-digital converter to settle
// after the last reading:
delay(50);
Cayenne.virtualWrite(Power_sensor, Power, "pow", "w");
}
CAYENNE_OUT(DayPower) {
Cayenne.virtualWrite(DayPower, PowerInDay, "pow", "w");
}
CAYENNE_OUT(MonthPower) {
Cayenne.virtualWrite(MonthPower, PowerInMonth, "pow", "w");
}
CAYENNE_IN(LED_PIN)
{
int currentValue = getValue.asInt();
if (currentValue == 1) {
PWM = 255;
digitalWrite(LED_PIN, HIGH);
} else {
PWM = 0;
digitalWrite(LED_PIN, LOW);
}
//digitalWrite(Relay, HIGH);
//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
}
CAYENNE_IN(LED_PWM)
{
int value = getValue.asInt(); // 0 to 255
PWM = value;
analogWrite(LED_PIN, value);
}
Finale 2 Version(Cayenne out_Default):
#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP8266Shield.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <virtuabotixRTC.h>
//Real+Virtual
#define LED_PIN 5
#define temp_sensor 4
#define EspSerial Serial
//Virtual
#define Power_sensor 9
#define DayPower 10
#define MonthPower 11
#define LED_PWM 12
//SSID
char ssid[] = "TP-LINK_MWNg";
char password[] = "mwngpass";
char username[] = "743674368676328742somenumbers";
char mqtt_password[] = "743674368676328742somenumbers";
char client_id[] = "743674368676328742somenumbers";
ESP8266 wifi(&EspSerial);
//Temperature setup
OneWire oneWire(4);
DallasTemperature sensors(&oneWire);
//Power sensor
const int analogInPin = A0;
int sensorValue = 0; // value read from the pot
float MAXValue = 0; // value output to the PWM (analog out)
float Power = 0;
int PWM = 0;
//Time
int curSec = 0;
int curMin = 0;
int curHour = 0;
int curDay = 0;
virtuabotixRTC myRTC(6, 7, 8);
unsigned PowerInDay = 0;
unsigned PowerInMonth = 0;
void setup() {
// put your setup code here, to run once:
sensors.begin();
EspSerial.begin(115200);
delay(10);
Cayenne.begin(username, mqtt_password, client_id, wifi, ssid, password);
pinMode(LED_PIN, OUTPUT);
analogWrite(LED_PIN, PWM);
curSec = myRTC.seconds;
curMin = myRTC.minutes;
curHour = myRTC.hours;
curDay = myRTC.dayofmonth;
//test
}
void loop() {
Cayenne.loop();
myRTC.updateTime();
if ( curSec != myRTC.seconds ) {
PowerInDay += Power;
curSec = myRTC.seconds;
}
if (curDay != myRTC.dayofmonth) {
PowerInMonth += PowerInDay;
PowerInDay = 0;
curDay = myRTC.dayofmonth;
}
if (curDay > myRTC.dayofmonth) {
PowerInMonth = 0;
}
Serial.print(myRTC.dayofmonth);
Serial.print('/');
Serial.print(myRTC.month);
Serial.print('/');
Serial.print(myRTC.year);
Serial.print('/');
Serial.print(' ');
Serial.print(myRTC.hours);
Serial.print(':');
Serial.print(myRTC.minutes);
Serial.print(':');
Serial.print(myRTC.seconds);
Serial.print('\n');
Serial.print(PowerInDay);
Serial.print(' ');
Serial.print(PowerInMonth);
Serial.print('\n');
}
CAYENNE_OUT_DEFAULT()
{
//Temp sensor-----------------------------------------
sensors.requestTemperatures();
Cayenne.celsiusWrite(temp_sensor, sensors.getTempCByIndex(0));
//Temp sensor-----------------------------------------
//Power sensor-------------------------------------------------
sensorValue = analogRead(analogInPin);
// map it to the range of the analog out:
if (sensorValue > 0)
MAXValue = sensorValue * 0.00007307;
Power = MAXValue * ((float)PWM / (float)255) * 3.3 * ((float)PWM / (float)255);
// change the analog out value:/
// print the results to the serial monitor:
Serial.print("sensor = ");
Serial.print(sensorValue); //RAW value from analog read :)
Serial.print("\t output = ");
Serial.println(MAXValue * ((float)PWM / (float)255), 3); //Output the current
Serial.print("Power =");
Serial.println(Power, 3);
// wait 2 milliseconds before the next loop
// for the analog-to-digital converter to settle
// after the last reading:
delay(50);
Cayenne.virtualWrite(Power_sensor, Power, "pow", "w");
//Power sensor-------------------------------------------------
//Power Day-------------------------------------------------
Cayenne.virtualWrite(DayPower, PowerInDay, "pow", "w");
//Power Month-------------------------------------------------
Cayenne.virtualWrite(MonthPower, PowerInMonth, "pow", "w");
}
CAYENNE_IN(LED_PIN)
{
int currentValue = getValue.asInt();
if (currentValue == 1) {
PWM = 255;
digitalWrite(LED_PIN, HIGH);
} else {
PWM = 0;
digitalWrite(LED_PIN, LOW);
}
//digitalWrite(Relay, HIGH);
//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
}
CAYENNE_IN(LED_PWM)
{
int value = getValue.asInt(); // 0 to 255
PWM = value;
analogWrite(LED_PIN, value);
}
Finale 3 Version(Send data with time difference):
#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP8266Shield.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <virtuabotixRTC.h>
//Real+Virtual
#define LED_PIN 5
#define temp_sensor 4
#define EspSerial Serial
//Virtual
#define Power_sensor 9
#define DayPower 10
#define MonthPower 11
#define LED_PWM 12
//SSID
char ssid[] = "TP-LINK_MWNg";
char password[] = "mwngpass";
char username[] = "743674368676328742somenumbers";
char mqtt_password[] = "743674368676328742somenumbers";
char client_id[] = "743674368676328742somenumbers";
ESP8266 wifi(&EspSerial);
//Temperature setup
OneWire oneWire(4);
DallasTemperature sensors(&oneWire);
//Power sensor
const int analogInPin = A0;
int sensorValue = 0; // value read from the pot
float MAXValue = 0; // value output to the PWM (analog out)
float Power = 0;
int PWM = 0;
//Time
int curSec = 0;
int curMin = 0;
int curHour = 0;
int curDay = 0;
virtuabotixRTC myRTC(6, 7, 8);
unsigned PowerInDay = 0;
unsigned PowerInMonth = 0;
int lastMillis = 0;
void setup() {
// put your setup code here, to run once:
sensors.begin();
EspSerial.begin(115200);
delay(10);
Cayenne.begin(username, mqtt_password, client_id, wifi, ssid, password);
pinMode(LED_PIN, OUTPUT);
analogWrite(LED_PIN, PWM);
curSec = myRTC.seconds;
curMin = myRTC.minutes;
curHour = myRTC.hours;
curDay = myRTC.dayofmonth;
//test
}
void loop() {
Cayenne.loop();
myRTC.updateTime();
if ( curSec != myRTC.seconds ) {
PowerInDay += Power;
curSec = myRTC.seconds;
}
if (curDay != myRTC.dayofmonth) {
PowerInMonth += PowerInDay;
PowerInDay = 0;
curDay = myRTC.dayofmonth;
}
if (curDay > myRTC.dayofmonth) {
PowerInMonth = 0;
}
// Serial.print(myRTC.dayofmonth);
// Serial.print('/');
// Serial.print(myRTC.month);
// Serial.print('/');
// Serial.print(myRTC.year);
// Serial.print('/');
// Serial.print(' ');
// Serial.print(myRTC.hours);
// Serial.print(':');
// Serial.print(myRTC.minutes);
// Serial.print(':');
// Serial.print(myRTC.seconds);
// Serial.print('\n');
// Serial.print(PowerInDay);
// Serial.print(' ');
// Serial.print(PowerInMonth);
// Serial.print('\n');
if(millis() - lastMillis > 10000 && millis() - lastMillis < 20000 ) {//Send data between 10 - 20 seconds
//Temp sensor-----------------------------------------
sensors.requestTemperatures();
Cayenne.celsiusWrite(temp_sensor, sensors.getTempCByIndex(0));
//Temp sensor-----------------------------------------
}
if(millis() - lastMillis > 20000 && millis() - lastMillis < 30000 ) {//Send data between 20 - 30 seconds
//Power sensor-------------------------------------------------
sensorValue = analogRead(analogInPin);
// map it to the range of the analog out:
if (sensorValue > 0)
MAXValue = sensorValue * 0.00007307;
Power = MAXValue * ((float)PWM / (float)255) * 3.3 * ((float)PWM / (float)255);
// change the analog out value:/
// print the results to the serial monitor:
Serial.print("sensor = ");
Serial.print(sensorValue); //RAW value from analog read :)
Serial.print("\t output = ");
Serial.println(MAXValue * ((float)PWM / (float)255), 3); //Output the current
Serial.print("Power =");
Serial.println(Power, 3);
// wait 2 milliseconds before the next loop
// for the analog-to-digital converter to settle
// after the last reading:
delay(50);
Cayenne.virtualWrite(Power_sensor, Power, "pow", "w");
//Power sensor-------------------------------------------------
}
if(millis() - lastMillis > 30000 && millis() - lastMillis < 40000 ) {//Send data between 30 - 40 seconds
//Power Day-------------------------------------------------
Cayenne.virtualWrite(DayPower, PowerInDay, "pow", "w");
}
if(millis() - lastMillis > 40000 && millis() - lastMillis < 50000 ) {//Send data between 40 - 50 seconds
//Power Month-------------------------------------------------
Cayenne.virtualWrite(MonthPower, PowerInMonth, "pow", "w");
lastMillis = millis();
}
}
CAYENNE_IN(LED_PIN)
{
int currentValue = getValue.asInt();
if (currentValue == 1) {
PWM = 255;
digitalWrite(LED_PIN, HIGH);
} else {
PWM = 0;
digitalWrite(LED_PIN, LOW);
}
//digitalWrite(Relay, HIGH);
//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
}
CAYENNE_IN(LED_PWM)
{
int value = getValue.asInt(); // 0 to 255
PWM = value;
analogWrite(LED_PIN, value);
}
Serial monitor message:
AT
ATE0
AT+CIPMUX=1
AT+CWMODE?
AT+CWJAP="TP-LINK_MWNg","mwngpass"
[5618] Connected to WiFi
[5619] Connecting to mqtt.mydevices.com:1883
AT+CIPSTART=1,"TCP","mqtt.mydevices.com",1883
[15636] Network connect failed
AT+CIPSTART=1,"TCP","mqtt.mydevices.com",1883
AT+CIPSEND=1,40
MQIsdp
9c6b2/things/743674368676328742somenumbersAT+CIPSEND=1,16
e7f5ba423/cmd/+
AT+CIPSEND=1,40
AT+CIPSEND=1,40
AT+CIPSEND=1,40
AT+CIPSEND=1,40
1i Zv1/743674368676328742somenumbersAT+CIPSEND=1,40
6b2/things/743674368676328742somenumbersAT+CIPSEND=1,27
f5ba423/data/4temp,c=28.125sensor = 0 output = 0.000
Power =0.000
AT+CIPSEND=1,40
1g
If your module is getting warm its probably a hardwareissue.I guess you use 5V for the esp module which is bad as it only needs 3.3V. It might survive 5V for a short time(moment) but don't stretch your luck. So you have to convert 5V ro 3.3V level shifter. You can not use the Arduino 3.3V output pin because it can not provide the power needed by the ESP (up to 250mA) vs. max 50mA on the Arduino (UNO) 3.3V pin.
The schematic shortly explained:
The ESP's VCC pin is powered by the 3.3V output pin of the voltage regulator (AMS1117 in the grphic).
The 10uF capacitor is connected to the output pins to stabilize the regulator.
The CH_PD pin must also be connected to 3.3V.
The GND pin is obviously connected to ground.
The ESP's TXD pin can be connected directly to the RX pin of Arduino (emulated on pin 6).
The ESP's RXD pin is connected to the TX pin of Arduino (emulated on pin 7) through the level shifter.
The last two can be changed depending if you use hardware or software serial EDIT
As you use rtc it makes no sense to update the time every loop this will crash your connection. Either do it every x hours and make sure with if/else that nochyenne loop() is running. It makes no sense to sync time every x millis() the syncing of time every hourisenough foryour scenario, I would go for once a day
I am having a problem with reading random data in my Arduino Mega (Master) from my Arduino Uno (Slave) while using I2C communication.
Some background: I am reading Encoder data from the Uno and sending to the Mega via I2C communication. The encoder data is been used in the MEga to adjust the speed of a motor so that the revolutions per second of the different wheels have the same value.
The issue of reading random data arises when I include an IF condition or function.
Even if the IF condition included is an empty one or a call to function which has an empty body it starts to read random wrong data from the Uno.
If i don't have the adjusting part (IF condition/ function) of the code the reading of the data from the Uno works fine.
If anybody can help, it would be greatly appreciated.
Master Code:
#include <SoftwareSerial.h>
#include <SabertoothSimplified.h>
// Include the required Wire library for I2C<br>#include
#include <Wire.h>
// RX on pin 17 (to S2), TX on pin 16 (to S1).
SoftwareSerial SWSerial(NOT_A_PIN, 16);
// Use SWSerial as the serial port.
SabertoothSimplified ST(SWSerial);
//////////////////ENCODER DATA//////////////////
unsigned int revolutions_L_rpm = 0;
unsigned int revolutions_R_rpm = 0;
int16_t x = 0;
int16_t y = 0;
////////////////////////////////////////////////
//////////////VARIABLES FOR ADJUST//////////////
int error = 0;
int kp = 12;
int adjusted = 0;
////////////////////////////////////////////////
////////////////////MOTORS//////////////////////
//Declare the arduino pins
int LEDg = 7;
int LEDr = 6;
int LEDy = 5;
int speedVar = 0;
int speedOne = 0;
int speedTwo = 0;
int power;
////////////////////END/////////////////////////
void setup() {
//initlize the mode of the pins
pinMode(LEDg,OUTPUT);
pinMode(LEDr,OUTPUT);
pinMode(LEDy,OUTPUT);
//set the serial communication rate
Serial.begin(9600);
SWSerial.begin(9600);
Wire.begin();
}
void loop()
{
//check whether arduino is reciving signal or not
if(Serial.available() > 0){
char val = Serial.read();//reads the signal
Serial.print("Recieved: ");
Serial.println(val);
switch(val){
/*********Increase speed by 1 as long as e(triangle) is held*********/
case 'a':
forward();
break;
/*********Decrease speed by 1 as long as g(x) is held*********/
case 'c':
reverse();
break;
/*********Increase speed by 1 as long as e(triangle) is held*********/
case 'd':
turnLeft();
break;
/*********Decrease speed by 1 as long as g(x) is held*********/
case 'b':
turnRight();
break;
/*********Toggle when Circle is held for 5 seconds*********/
case 'f':
toggleSwitch(LEDy);
break;
/*********Toggle when Square is held for 5 seconds*********/
case 'h':
stopMotors();
break;
}
Serial.print("sppedVar = ");
Serial.print(speedVar);
Serial.print("\tleftSpeed: ");
Serial.print(speedOne);
Serial.print("\trightSpeed: ");
Serial.println(speedTwo);
}
Wire.requestFrom(9,4); // Request 4 bytes from slave arduino (9)
byte a = Wire.read();
Serial.print("a: ");
Serial.print(a);
byte b = Wire.read();
Serial.print(" b: ");
Serial.print(b);
byte e = Wire.read();
Serial.print(" --- e: ");
Serial.print(e);
byte f = Wire.read();
Serial.print(" f: ");
Serial.print(f);
x = a;
x = (x << 8) | b;
Serial.print("\tX: ");
Serial.print(x);
y = e;
y = (y << 8) | f;
Serial.print("\tY: ");
Serial.print(y);
revolutions_L_rpm = x;
revolutions_R_rpm = y;
if ((revolutions_L_rpm != revolutions_R_rpm) && (speedVar != 0)){
error = 0;
error = revolutions_L_rpm - revolutions_R_rpm;
adjusted = error/kp;
Serial.print("Error: ");
Serial.print(error);
Serial.print("Error/kp: ");
Serial.println(adjusted);
if ((speedTwo < 20) && (speedTwo > -20)){
speedTwo -= adjusted;
power = speedTwo;
ST.motor(2, -power);
//delay(20);
}
}
// Print out rpm
Serial.print("Left motor rps*100: ");
Serial.print(revolutions_L_rpm);
Serial.print(" ///// Right motor rps*100: ");
Serial.println(revolutions_R_rpm);
// Print out speed
Serial.print("speedOne: ");
Serial.print(speedOne);
Serial.print("\tspeedTwo: ");
Serial.println(speedTwo);
delay(1000);
}
Slave code:
// Include the required Wire library for I2C<br>#include <Wire.h>
#include <Wire.h>
// Checked for main program
volatile boolean counterReady;
// Internal to counting routine
unsigned int timerPeriod;
unsigned int timerTicks;
unsigned long overflowCount;
// The pin the encoder is connected
int encoder_in_L = 2;
int encoder_in_R = 3;
// The number of pulses per revolution
// depends on your index disc!!
unsigned int pulsesperturn = 16;
// The total number of revolutions
int16_t revolutions_L = 0;
int16_t revolutions_R = 0;
int16_t revolutions_L_rpm = 0;
int16_t revolutions_R_rpm = 0;
// Initialize the counter
int16_t pulses_L = 0;
int16_t pulses_R = 0;
byte myData[4];
// This function is called by the interrupt
void count_L() {
pulses_L++;
}
void count_R() {
pulses_R++;
}
void startCounting(unsigned int ms) {
counterReady = false; // time not up yet
timerPeriod = ms; // how many ms to count to
timerTicks = 0; // reset interrupt counter
overflowCount = 0; // no overflows yet
// Reset timer 2
TCCR2A = 0;
TCCR2B = 0;
// Timer 2 - gives us our 1 ms counting interval
// 16 MHz clock (62.5 ns per tick) - prescaled by 128
// counter increments every 8 µs.
// So we count 125 of them, giving exactly 1000 µs (1 ms)
TCCR2A = bit (WGM21) ; // CTC mode
OCR2A = 124; // count up to 125 (zero relative!!!!)
// Timer 2 - interrupt on match (ie. every 1 ms)
TIMSK2 = bit (OCIE2A); // enable Timer2 Interrupt
TCNT2 = 0; // set counter to zero
// Reset prescalers
GTCCR = bit (PSRASY); // reset prescaler now
// start Timer 2
TCCR2B = bit (CS20) | bit (CS22) ; // prescaler of 128
}
ISR (TIMER2_COMPA_vect){
// see if we have reached timing period
if (++timerTicks < timerPeriod)
return;
TCCR2A = 0; // stop timer 2
TCCR2B = 0;
TIMSK2 = 0; // disable Timer2 Interrupt
counterReady = true;
if(counterReady){
Serial.print("Pulses_L: ");
Serial.print(pulses_L);
Serial.print(" Pulses_R: ");
Serial.println(pulses_R);
// multiplying by 100 to get a greater difference to compare
revolutions_L_rpm = (pulses_L * 100) / pulsesperturn;
revolutions_R_rpm = (pulses_R * 100) / pulsesperturn;
// Total revolutions
// revolutions_L = revolutions_L + (pulses_L / pulsesperturn);
// revolutions_R = revolutions_R + (pulses_R / pulsesperturn);
pulses_L = 0;
pulses_R = 0;
}
}
void requestEvent() {
myData[0] = (revolutions_L_rpm >> 8) & 0xFF;
myData[1] = revolutions_L_rpm & 0xFF;
myData[2] = (revolutions_R_rpm >> 8) & 0xFF;
myData[3] = revolutions_R_rpm & 0xFF;
Wire.write(myData, 4); //Sent 4 bytes to master
}
void setup() {
Serial.begin(9600);
pinMode(encoder_in_L, INPUT);
pinMode(encoder_in_R, INPUT);
attachInterrupt(0, count_L, RISING); //attachInterrupt(digitalPinToInterrupt(encoder_in_L, count_L, RISING);
attachInterrupt(1, count_R, RISING); //attachInterrupt(digitalPinToInterrupt(encoder_in_R, count_R, RISING);
// Start the I2C Bus as Slave on address 9
Wire.begin(9);
// Attach a function to trigger when something is received.
Wire.onRequest(requestEvent);
}
void loop() {
// stop Timer 0 interrupts from throwing the count out
byte oldTCCR0A = TCCR0A;
byte oldTCCR0B = TCCR0B;
TCCR0A = 0; // stop timer 0
TCCR0B = 0;
startCounting (1000); // how many ms to count for
while (!counterReady)
{ } // loop until count over
// Print out rpm
Serial.print("Left motor rps: ");
Serial.println(revolutions_L_rpm);
Serial.print("Right motor rps: ");
Serial.println(revolutions_R_rpm);
// Print out revolutions
// Serial.print("Left motor revolution count: ");
// Serial.println(revolutions_L);
// Serial.print("Right motor revolution count: ");
// Serial.println(revolutions_R);
// restart timer 0
TCCR0A = oldTCCR0A;
TCCR0B = oldTCCR0B;
delay(200);
}
I am trying to interface an ADNS 9800 mouse chip which I took from "Sharkoon SHARK ZONE M50" . The original PCB is still in place.
I am trying to obtain a framecapture, which should be 30 x 30 pixels. I have connected the ADNS 9800 with SPI to an Arduino UNO Rev 3 (i.e. 5V operating voltage). I.e. MISO, MOSI, SCLK, DGND, AGND, NCS. I did not connect any voltage, since I concluded from previous attempts that that did not yield a good frame capture.
The current problem is that I get a frame capture that is divided in 3 parts: square top left (with a good image of the surroundings), square bottom left (which is a duplicate of top left) and a rectangle on the right half of the screen of monotone grey colour (which does change depending on light conditions). See image. I want the full screen to be one image, not the divided mess it is now. Therefore, it may be a question of the resolution that is used, it may be that it is 15x15 instead of 30x30. However I do not know where this is determined/set.
Also, I find it strange that no input voltage seems to be needed to obtain an image from the camera.
See attachments for frame capture and code (arduino + processing).
Frame output
Arduino code
#include
#include
// Registers
#define REG_Product_ID 0x00
#define REG_Revision_ID 0x01
#define REG_Motion 0x02
#define REG_Delta_X_L 0x03
#define REG_Delta_X_H 0x04
#define REG_Delta_Y_L 0x05
#define REG_Delta_Y_H 0x06
#define REG_SQUAL 0x07
#define REG_Pixel_Sum 0x08
#define REG_Maximum_Pixel 0x09
#define REG_Minimum_Pixel 0x0a
#define REG_Shutter_Lower 0x0b
#define REG_Shutter_Upper 0x0c
#define REG_Frame_Period_Lower 0x0d
#define REG_Frame_Period_Upper 0x0e
#define REG_Configuration_I 0x0f
#define REG_Configuration_II 0x10
#define REG_Frame_Capture 0x12
#define REG_SROM_Enable 0x13
#define REG_Run_Downshift 0x14
#define REG_Rest1_Rate 0x15
#define REG_Rest1_Downshift 0x16
#define REG_Rest2_Rate 0x17
#define REG_Rest2_Downshift 0x18
#define REG_Rest3_Rate 0x19
#define REG_Frame_Period_Max_Bound_Lower 0x1a
#define REG_Frame_Period_Max_Bound_Upper 0x1b
#define REG_Frame_Period_Min_Bound_Lower 0x1c
#define REG_Frame_Period_Min_Bound_Upper 0x1d
#define REG_Shutter_Max_Bound_Lower 0x1e
#define REG_Shutter_Max_Bound_Upper 0x1f
#define REG_LASER_CTRL0 0x20
#define REG_Observation 0x24
#define REG_Data_Out_Lower 0x25
#define REG_Data_Out_Upper 0x26
#define REG_SROM_ID 0x2a
#define REG_Lift_Detection_Thr 0x2e
#define REG_Configuration_V 0x2f
#define REG_Configuration_IV 0x39
#define REG_Power_Up_Reset 0x3a
#define REG_Shutdown 0x3b
#define REG_Inverse_Product_ID 0x3f
#define REG_Snap_Angle 0x42
#define REG_Motion_Burst 0x50
#define REG_SROM_Load_Burst 0x62
#define REG_Pixel_Burst 0x64
byte initComplete=0;
byte testctr=0;
unsigned long currTime;
unsigned long timer;
volatile int xdat;
volatile int ydat;
volatile byte movementflag=0;
const int ncs = 10;
const int lsPin = 4;//ANALOG
const int linearActPin = 9;
extern const unsigned short firmware_length;
extern const unsigned char firmware_data[];
String parseChar = ".";
void setup() {
Serial.begin(115200);
//For first parse put LF and CR there
Serial.println("");
//pinMode(ls, INPUT);
//ADNS 9800 setup
pinMode (ncs, OUTPUT);
SPI.begin();
SPI.setDataMode(SPI_MODE3);
SPI.setBitOrder(MSBFIRST);
//Set clock to 2 MHz
SPI.setClockDivider(8);
performStartup();
dispRegisters();
delay(100);
//Pin modes
pinMode(linearActPin, OUTPUT);
Serial.print("Ready");
Serial.println(parseChar);
//Serial.println("Device is ready");
//FrameCapture();
}
/* DO NOT EDIT BELOW; NECESSARY FOR ADNS9800 */
void performStartup(void){
// reset the chip
adns_com_end(); // ensure that the serial port is reset
adns_com_begin(); // ensure that the serial port is reset
adns_com_end(); // ensure that the serial port is reset
adns_write_reg(REG_Power_Up_Reset, 0x5a); // force reset
delay(50); // wait for it to reboot
// read registers 0x02 to 0x06 (and discard the data)
adns_read_reg(REG_Delta_X_L);
adns_read_reg(REG_Delta_X_H);
adns_read_reg(REG_Delta_Y_L);
adns_read_reg(REG_Delta_Y_H);
// upload the firmware
adns_upload_firmware();
delay(10);
//enable laser(bit 0 = 0b), in normal mode (bits 3,2,1 = 000b)
// reading the actual value of the register is important because the real
// default value is different from what is said in the datasheet, and if you
// change the reserved bytes (like by writing 0x00...) it would not work.
byte laser_ctrl0 = adns_read_reg(REG_LASER_CTRL0);
adns_write_reg(REG_LASER_CTRL0, laser_ctrl0 & 0xf1 );
//0x08 = enable fixed framerate, leave rest standard
//0x10 = disable AGC, leave rest standard
adns_write_reg(REG_Configuration_II, 0x08);
//Set resolution; cpi = REG_value x50
//Min: 0x01 50 cpi
//Max: 0xA4 8200 cpi
adns_write_reg(REG_Configuration_I, 0xA4);
//Set fixed framerate: FR = clk_freq/REG_value = 2000 fps
adns_write_reg(REG_Frame_Period_Max_Bound_Lower, 0xa8);
adns_write_reg(REG_Frame_Period_Max_Bound_Upper, 0x61);
//Set shutter time
adns_write_reg(REG_Shutter_Max_Bound_Lower,0x00);
adns_write_reg(REG_Shutter_Max_Bound_Upper,0x08);
//adns_write_reg(REG_Snap_Angle, 0x80);
delay(1);
Serial.print("Initialized");
Serial.println(parseChar);
}
void adns_com_begin(){
digitalWrite(ncs, LOW);
}
void adns_com_end(){
digitalWrite(ncs, HIGH);
}
byte adns_read_reg(byte reg_addr){
adns_com_begin();
// send adress of the register, with MSBit = 0 to indicate it's a read
SPI.transfer(reg_addr & 0x7f );
delayMicroseconds(100); // tSRAD
// read data
byte data = SPI.transfer(0);
delayMicroseconds(1); // tSCLK-NCS for read operation is 120ns
adns_com_end();
delayMicroseconds(19); // tSRW/tSRR (=20us) minus tSCLK-NCS
return data;
}
void adns_write_reg(byte reg_addr, byte data){
adns_com_begin();
//send adress of the register, with MSBit = 1 to indicate it's a write
SPI.transfer(reg_addr | 0x80 );
//sent data
SPI.transfer(data);
delayMicroseconds(20); // tSCLK-NCS for write operation
adns_com_end();
delayMicroseconds(100); // tSWW/tSWR (=120us) minus tSCLK-NCS. Could be shortened, but is looks like a safe lower bound
}
void adns_upload_firmware(){
// send the firmware to the chip, cf p.18 of the datasheet
//Serial.println("Uploading firmware...");
// set the configuration_IV register in 3k firmware mode
adns_write_reg(REG_Configuration_IV, 0x02); // bit 1 = 1 for 3k mode, other bits are reserved
// write 0x1d in SROM_enable reg for initializing
delay(10);
adns_write_reg(REG_SROM_Enable, 0x1d);
// wait for more than one frame period
delay(10); // assume that the frame rate is as low as 100fps... even if it should never be that low
// write 0x18 to SROM_enable to start SROM download
adns_write_reg(REG_SROM_Enable, 0x18);
// write the SROM file (=firmware data)
adns_com_begin();
//write burst destination adress
//bitwise OR to ensure MSB is 1
SPI.transfer(REG_SROM_Load_Burst | 0x80);
delayMicroseconds(50);
// send all bytes of the firmware
unsigned char c;
for(int i = 0; i < firmware_length; i++){
c = (unsigned char)pgm_read_byte(firmware_data + i);
SPI.transfer(c);
delayMicroseconds(15);
}
adns_com_end();
}
void adns_frame_capture(){
//Send signal to start datacollection frame capture
Serial.print("Frame capture");
Serial.println(parseChar);
// reset the chip
adns_write_reg(REG_Power_Up_Reset, 0x5a); // force reset
delay(50); // wait for it to reboot
delay(10);
//Write bytes to Frame_Capture
adns_write_reg(REG_Frame_Capture, 0x93);
adns_write_reg(REG_Frame_Capture, 0xc5);
// wait for more than two frame periods
delay(25); // assume that the frame rate is as low as 100fps... even if it should never be that low
//Check for the first pixel bij reading bit zero of Motion register
//If it is 1, first pixel available
byte motion = adns_read_reg(REG_Motion);
adns_com_begin();
delayMicroseconds(120);//delay t-SRAD = 100 us
byte pixel_burst;
if (motion == 0x21){
//Reading pixel values from ADNS and storing them in Array
for(int i = 0; i < 900; i++){
pixel_burst = adns_read_reg(REG_Pixel_Burst);
//Serial.print(i);
//Serial.print(":");
Serial.print(String(pixel_burst));
Serial.println(parseChar);
delayMicroseconds(15);
}
//Finished transmitting data
Serial.print("Data transfer finished");
Serial.println(parseChar);
//Transfer surface quality value
Serial.print("SQUAL");
Serial.print(String(adns_read_reg(REG_SQUAL)));
Serial.println(parseChar);
}else {
Serial.print("Frame capture failed");
Serial.println(parseChar);
}
adns_com_end();
//Hardware reset and firmware restore required to return navigation
performStartup();
}
void dispRegisters(void){
int oreg[7] = {
0x00,0x3F,0x2A,0x02 };
char* oregname[] = {
"Product_ID","Inverse_Product_ID","SROM_Version","Motion" };
byte regres;
digitalWrite(ncs,LOW);
int rctr=0;
for(rctr=0; rctr<4; rctr++){
SPI.transfer(oreg[rctr]);
delay(1);
//Serial.println("---");
//Serial.println(oregname[rctr]);
//Serial.println(oreg[rctr],HEX);
regres = SPI.transfer(0);
//Serial.println(regres,BIN);
//Serial.println(regres,HEX);
delay(1);
}
digitalWrite(ncs,HIGH);
}
/*********************************************************
DO NOT EDIT ABOVE; NECESSARY FOR RUNNING ADNS9800
*********************************************************/
String data = String();
//Process variables
int run = 0;
int t = 0;
unsigned long t_ms, t_us;
int dt = 0;//1/f = [ms]
long int t_run = 0;//[ms]
unsigned long ms_start, us_start;
void loop() {
if (dt == -1 || t_run == -1){
Serial.print("Time constant error");
Serial.println(parseChar);
}else if (run == 1 && t<t_run){
measure();
Serial.print(data);
Serial.println("");
Serial.println(parseChar);
}else if(run == 1 && t>=t_run){
//Measurement finished
Serial.print("Measurement finished");
Serial.println(parseChar);
digitalWrite(linearActPin, LOW);
run = 0;
t = 0;
}
}
void serialEvent(){
String data_rx;
if (Serial.available() > 0){
//Parse serial data until '.'
data_rx = Serial.readStringUntil('.');
//Remove '.' from buffer
data_rx = data_rx.substring(0, data_rx.length());
//Serial.print(data_rx);
if (data_rx.equals("Run")){
run = 1;
ms_start = millis();
us_start = micros();
digitalWrite(linearActPin, HIGH);
//Read registers and discard data
byte XDataL = adns_read_reg(REG_Delta_X_L);
byte XDataH = adns_read_reg(REG_Delta_X_H);
byte YDataL = adns_read_reg(REG_Delta_Y_L);
byte YDataH = adns_read_reg(REG_Delta_Y_H);
}else if(data_rx.equals("Frame capture run")){
adns_frame_capture();
}else if(data_rx.equals("SQUAL")){
Serial.println(String(adns_read_reg(REG_SQUAL)));
}else if(data_rx.startsWith("dt")){
dt = data_rx.substring(2,data_rx.length()).toInt();
}else if(data_rx.startsWith("trun")){
t_run = data_rx.substring(4,data_rx.length()).toInt();
}
}
}
void measure(void){
/*READ dx, dy, ls
increment t with dt
return String "t,dx,dy,ls"*/
//Read optic flow from ADNS
byte XDataL = adns_read_reg(REG_Delta_X_L);
byte XDataH = adns_read_reg(REG_Delta_X_H);
byte YDataL = adns_read_reg(REG_Delta_Y_L);
byte YDataH = adns_read_reg(REG_Delta_Y_H);
int ls;
unsigned long us, ms;
xdat = int(XDataH<<8);
ydat = int(YDataH<<8);
xdat |=int(XDataL);
ydat |=int(YDataL);
//int between 0-1023, with 5V/1024 = 0.0049 V/unit
ls = analogRead(lsPin);
//Calculate time elapsed between measurements
ms = millis();
us = micros();
t_ms = ms-ms_start;
t_us = us-us_start;
t = t_ms;
//Convert datatypes to string objects and combine
//us can always be divided by 4, so accurate to a resolution of 4 us
String d1 = String(t_ms);
String d2 = String(t_us);
String d3 = String(xdat);
String d4 = String(ydat);
String d5 = String(ls);
data = d2+","+d3+","+d4+","+d5;
//Increment time
delay(dt);
}
Processing code
/* BEP experiment
Communicates with arduino to conduct experiment
Receives and stores data
/
/ DATA PROTOCOL
data_rx
R start measuring
S do screendump
D device is ready
F measurement finished
/
import processing.serial.;
import controlP5.*;
//Serial COMM
Serial arduino;
String data_rx, data_tx;
String parseChar = ".";
//GUI
ControlP5 cp5;
Textfield txtfldDistance, txtfldSpeed, txtfldTs, txtfldN,
txtfldFl, txtfldBron, txtfldPattern, txtfldTrun;
Button btnRun, btnStop, btnFrame;
//File I/O
PrintWriter writer;
String path;
//Runtime variables
int run = 0;
int createWriter = 0;
int frameCapture = 0;
int frameDisplay = 0;
//Time management
String timestamp;
int ms, ms_start;
final int frameX = 30;
final int frameY = 30;
void setup() {
frameRate(60);
time();
//Create GUI
textSize(20);
size(360,660);
//Create textboxes
cp5 = new ControlP5(this);
txtfldDistance = cp5.addTextfield("Distance[m]:")
.setPosition(30, 30)
.setSize(70, 30)
.setAutoClear(false)
.setText("0.5");
txtfldSpeed = cp5.addTextfield("Speed[rev/s]:")
.setPosition(30, 90)
.setSize(70, 30)
.setAutoClear(false);
txtfldTs = cp5.addTextfield("t_s[ms]")
.setPosition(30, 150)
.setSize(70, 30)
.setAutoClear(false)
.setText("10");
txtfldTrun = cp5.addTextfield("t_run[s]")
.setPosition(30, 210)
.setSize(70, 30)
.setAutoClear(false);
txtfldFl = cp5.addTextfield("f[mm]")
.setPosition(130, 30)
.setSize(70, 30)
.setAutoClear(false)
.setText("14");
txtfldBron = cp5.addTextfield("Bron[Watt]")
.setPosition(130, 90)
.setSize(70, 30)
.setAutoClear(false)
.setText("40");
txtfldPattern = cp5.addTextfield("Pattern[mm]")
.setPosition(130, 150)
.setSize(70, 30)
.setAutoClear(false)
.setText("random");
txtfldN = cp5.addTextfield("n")
.setPosition(130, 210)
.setSize(70, 30)
.setAutoClear(false)
.setText("1");
btnRun = cp5.addButton("Run")
.setPosition(230, 270)
.setSize(50,30)
.lock();
btnStop = cp5.addButton("Stop")
.setPosition(150, 270)
.setSize(50,30)
.lock();
btnFrame = cp5.addButton("Frame_Capture")
.setPosition(30, 270)
.setSize(90,30)
.lock();
//Create Serial COMM object
print(timestamp+"SERIAL PORT: ");
println(Serial.list());
// List all the available serial ports:
//arduino = new Serial(this, Serial.list()[2], 115200);
arduino = new Serial(this, Serial.list()[0], 115200);
arduino.clear();
arduino.bufferUntil('.');
}
void draw() {
time();
Frame_Capture();
display_frame();
if (frameDisplay == 1){
display_frame();
frameDisplay = 0;
println(timestamp+"---------------------");
}
}
int n = 0;
int[] frame_capture_data = new int[900];
void serialEvent(Serial arduino){
if (arduino.available() > 0){
//Parse serial data until '.'
data_rx = arduino.readStringUntil('.');
//Remove CR, LF and '.' from buffer
data_rx = data_rx.substring(2, data_rx.length()-1);
//print(n+":");
//println(data_rx);
if(data_rx.equals("Data transfer finished")){
println(timestamp+"Data transfer finished.");
println(timestamp+"Generating visual.");
frameCapture = 0;
frameDisplay = 1;
n = 0;
//unlock textfields
txtfldSpeed.unlock();
txtfldDistance.unlock();
txtfldTs.unlock();
txtfldBron.unlock();
txtfldPattern.unlock();
txtfldFl.unlock();
txtfldN.unlock();
btnRun.unlock();
btnStop.unlock();
btnFrame.unlock();
}else if(data_rx.equals("Ready")){
println(timestamp+"Device is ready.");
println(timestamp+"---------------------");
//unlock textfields
btnRun.unlock();
btnStop.unlock();
btnFrame.unlock();
}else if(data_rx.equals("Initialized")){
println(timestamp+"Device is initialized.");
}else if(data_rx.equals("Measurement finished")){
println(timestamp+"Measurement completed.");
Stop();
}else if(data_rx.equals("Frame capture")){
println(timestamp+"Frame capture transfer started.");
frameCapture = 1;
}else if(data_rx.equals("Frame capture failed")){
println(timestamp+"Frame capture failed. Try again.");
println(timestamp+"---------------------");
//unlock textfields
txtfldSpeed.unlock();
txtfldDistance.unlock();
txtfldTs.unlock();
txtfldBron.unlock();
txtfldPattern.unlock();
txtfldFl.unlock();
txtfldN.unlock();
btnRun.unlock();
btnStop.unlock();
btnFrame.unlock();
}else if(data_rx.contains("SQUAL")){
print(timestamp+"SQUAL: ");
println(data_rx.substring(5,data_rx.length()));
}else if(data_rx.equals("Time constant error")){
print(timestamp+"TIME CONSTANT ERROR");
}else if(frameCapture == 1 && n < 900){
frame_capture_data[n] = int(data_rx);
n++;
}else if(run == 1){
//print(data_rx);
writer.print(data_rx);
}
}
}
public void Run() {
/* When RUN is pressed program starts to run */
//Read value to determine path
float speed = float(txtfldSpeed.getText());
float distance = float(txtfldDistance.getText());
int t_s = int(txtfldTs.getText());
int bron = int(txtfldBron.getText());
int fl = int(txtfldFl.getText());
String pattern = txtfldPattern.getText();
String date = day()+"-"+month();
int n = int(txtfldN.getText());
// Create CSV data file, showing the results from experiment
if (speed > 0 && distance > 0){
if (createWriter == 0){
//Creating objects for writing to file
path = "data/"+date+"/x="+distance+"/"+"x="+distance+"_v="+speed+
"_ts="+t_s+"_f="+fl+"_bron="+bron+"_pat="+pattern+"_n="+n+".csv";
writer = createWriter(path);
//Runtime variables
createWriter = 1;
run = 1;
ms_start = millis();
//Transmit t_s en t_run
arduino.write("dt"+txtfldTs.getText());
arduino.write(parseChar);
arduino.write("trun"+int(txtfldTrun.getText())*1000);
arduino.write(parseChar);
//Transmit starting char to arduino
arduino.write("Run");
arduino.write(parseChar);
//Header
//writer.println("t_ard_ms,t_ard_us,dx,dy,ls");
//lock textfields
txtfldSpeed.lock();
txtfldDistance.lock();
txtfldTs.lock();
txtfldBron.lock();
txtfldPattern.lock();
txtfldFl.lock();
txtfldN.lock();
btnRun.lock();
btnStop.lock();
btnFrame.lock();
println(timestamp+"PROGRAM INITIATED");
println(timestamp+"File stored at: "+path);
}
//ERROR messages
} else if (speed <= 0 && distance <= 0){
println(timestamp+"ERROR: INVALID SPEED AND DISTANCE");
} else if (speed <= 0){
println(timestamp+"ERROR: INVALID SPEED");
} else if (distance <= 0){
println(timestamp+"ERROR: INVALID DISTANCE ");
} else if(txtfldSpeed.getText().equals("")){
println(timestamp+"ERROR: Enter paramaters.");
}
}
public void Stop() {
/* When STOP is pressed program terminates and writes to file */
if (createWriter == 1){
//Write to file and close stream
writer.flush();
writer.close();
//Runtime variables
run = 0;
createWriter = 0;
//unlock textfields
txtfldSpeed.unlock();
txtfldDistance.unlock();
txtfldTs.unlock();
txtfldBron.unlock();
txtfldPattern.unlock();
txtfldFl.unlock();
txtfldN.unlock();
btnRun.unlock();
btnStop.unlock();
btnFrame.unlock();
txtfldN.setText(str(int(txtfldN.getText())+1));
if (int(txtfldN.getText()) > 5){
txtfldN.setText("1");
txtfldSpeed.clear();
}
println(timestamp+"Data written to file.");
println(timestamp+"---------------------");
}
}
public void Frame_Capture() {
arduino.write("Frame capture run");
arduino.write(parseChar);
//lock textfields
txtfldSpeed.lock();
txtfldDistance.lock();
txtfldTs.lock();
txtfldBron.lock();
txtfldPattern.lock();
txtfldFl.lock();
txtfldN.lock();
btnRun.lock();
btnStop.lock();
btnFrame.lock();
}
void display_frame(){
int[] frame1 = new int[225];
int[] frame2 = new int[255];
int x = 30;
int y = 320;
//resolutie 10x10
int s = 10; // size of pixel, i.e. side lengths
//Max res is 30x30
int sz = 10;
int res = 30;
for (int i = 0; i < 15; i++){
for (int m = 0; m < 15; m++){
frame1[15*i+m] = frame_capture_data[30*i+m];
frame2[15*i+m] = frame_capture_data[30*i+m+15];
}
}
//for (int i = 0; i < res*res; i++){
//Commented by Daan:
//for (int j = 0; j < res; j++){ // j resembles the column index.
// for (int k = 0; k < res; k++){ // k resembles the row index
// //fill(map(frame_capture_data[30*j+k],0,63,0,255));
// //frame_capture_data[30*j+k] = 300; // test to see how the pixel values can be manipulated
// fill(float(frame_capture_data[30*j+k]));
// rect(x+j*10, y+300-k*10, s, s);
// //println(frame_capture_data[30*j+k]);
// }
//}
for( int i = 0; i < 900; i++ )
{
fill( map(frame_capture_data[i], 0, 63, 0, 255) ); // Convert from ADNS greyscale to 0 - 255 grey scale format.
rect(x + (i / frameX * sz), // Each rect() is a rectangle that represents a pixel. I.e. width and height of each pixel is "sz".
y +300 - (i % frameY * sz),
sz, sz);
// //rect(off_x + (i % frameX * sz), // Each rect() is a rectangle that represents a pixel. I.e. width and height of each pixel is "sz".
// //off_y + (i / frameY * sz),
// //sz, sz);
}
fill(255,0,0);
rect(x+3*10, y+300-8*10, s, s); // this is red test dot, j = 3 (column), k = 8 (row).
// I.e. this is the 30*3 + 8 = 98 th pixel in frame stream from sensor.
}
public void time(){
/* Keeps track of time
Creates timestamp for messages*/
String h = str(hour());
String m = str(minute());
String s = str(second());
if (int(h) < 10){
h = "0"+h;
} else if(int(m) < 10){
m = "0"+m;
} else if(int(s) < 10){
s = "0"+s;
}
timestamp = "["+h+":"+m+":"+s+"] ";
}
I am having a problem with my relay switches. I have a 5V, four relay switch for use with an Arduino. I am trying to make it so that when I push a button, one relay goes on and then, when I press it again, the same relay goes off.
This concept works with the code when using one relay. However, the problem is that my code works for one relay and one relay only. If I change the code and make multiple variables, it will not work.
FYI, I am using an Arduino UNO R3 ATmega 328
Keep in mind that this first code does work, but only for one relay. It works when I press the button to turn it on and then pressing the button again turns it off.
const int rl1 = 7;
const int rl2 = 12;
const int rl3 = 2;
const int rl4 = 8;
const int button1 = 11;
const int button2 = 10;
const int button3 = 3;
const int button4 = 4;
int rl1State = LOW;
int rl2State = LOW;
int rl3State = LOW;
int rl4State = LOW;
int buttonState = LOW;
int lastButtonState = HIGH;
int reading;
long lastDebounceTime=0;
long debounceDelay = 50;
void setup() {
Serial.begin(9600);
pinMode(rl1, OUTPUT);
pinMode(rl2, OUTPUT);
pinMode(rl3, OUTPUT);
pinMode(rl3, OUTPUT);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
pinMode(button3, INPUT);
pinMode(button4, INPUT);
}
void loop() {
reading = digitalRead(button1);
if(reading != lastButtonState){
lastDebounceTime = millis();
lastButtonState = reading;
}
if((millis() - lastDebounceTime) > debounceDelay){
if(buttonState != lastButtonState){
buttonState = lastButtonState;
if(buttonState == HIGH){
rl1State = !rl1State;
digitalWrite(rl1, rl1State);
}
}
}
}
I tried this code for multiple relays:
const int rl1 = 7;
const int rl2 = 12;
const int rl3 = 2;
const int rl4 = 8;
const int button1 = 11;
const int button2 = 10;
const int button3 = 3;
const int button4 = 4;
int rl1State = LOW;
int rl2State = LOW;
int rl3State = LOW;
int rl4State = LOW;
//States
int buttonState1 = LOW;
int lastButtonState1 = HIGH;
int buttonState2 = LOW;
int lastButtonState2 = HIGH;
int buttonState3 = LOW;
int lastButtonState3 = HIGH;
int buttonState4 = LOW;
int lastButtonState4 = HIGH;
//Read State
int reading1;
int reading2;
int reading3;
int reading4;
long lastDebounceTime1=0;
long debounceDelay1 = 50;
long lastDebounceTime2=0;
long debounceDelay2 = 50;
long lastDebounceTime3=0;
long debounceDelay3= 50;
long lastDebounceTime4=0;
long debounceDelay4 = 50;
void setup() {
Serial.begin(9600);
pinMode(rl1, OUTPUT);
pinMode(rl2, OUTPUT);
pinMode(rl3, OUTPUT);
pinMode(rl3, OUTPUT);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
pinMode(button3, INPUT);
pinMode(button4, INPUT);
}
void loop() {
reading1 = digitalRead(button1);
reading2 = digitalRead(button2);
reading3 = digitalRead(button3);
reading4 = digitalRead(button4);
//Relay 1
if(reading1 != lastButtonState1){
lastDebounceTime1 = millis();
lastButtonState1 = reading1;
}
if(reading1 != lastButtonState1){
lastDebounceTime1 = millis();
lastButtonState1 = reading1;
}
if((millis() - lastDebounceTime1) > debounceDelay1){
if(buttonState1 != lastButtonState1){
buttonState1 = lastButtonState1;
if(buttonState1 == HIGH){
rl1State = !rl1State;
digitalWrite(rl1, rl1State);
}
}
}
//Relay 2
if(reading2 != lastButtonState2){
lastDebounceTime2 = millis();
lastButtonState2 = reading2;
}
if((millis() - lastDebounceTime2) > debounceDelay2){
if(buttonState2 != lastButtonState2){
buttonState2 = lastButtonState2;
if(buttonState2 == HIGH){
rl2State = !rl2State;
digitalWrite(rl2, rl2State);
}
}
}
}
I also tried to re-make all the variables for each button and relay, but it still does not work.
On another note, one of my relays does not work when put to any pin (when all the pins are connected) but it works only when one of the pins are disconnected. It's really weird. I tested the relay and it's fine and I changed the Arduino but still have the same issue.
AH! This will work here is the code and the schematics for all of you that have this problem (saw on the internet a lot do have this problem), as well THANK YOU ALL for you help in solving this matter! ENJOY!
Circuit (Please note the relay cluster I am using was not available on Fritzing)
Code:
//Buttons
int button1 = 7;
int button2 = 6;
int button3 = 4;
int button4 = 2;
//Relays
int rl1 = 13;
int rl2 = 12;
int rl3 = 11;
int rl4 = 8;
//States for Relay and Button (1)
int state1 = HIGH; // the current state of the output pin
int reading1; // the current reading from the input pin
int previous1 = LOW; // the previous reading from the input pin
//States for Relay and Button (2)
int state2 = HIGH; // the current state of the output pin
int reading2; // the current reading from the input pin
int previous2 = LOW; // the previous reading from the input pin
//States for Relay and Button (3)
int state3 = HIGH; // the current state of the output pin
int reading3; // the current reading from the input pin
int previous3 = LOW; // the previous reading from the input pin
//States for Relay and Button (4)
int state4 = HIGH; // the current state of the output pin
int reading4; // the current reading from the input pin
int previous4 = LOW; // the previous reading from the input pin
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time1 = 0; // the last time the output pin was toggled
long time2 = 0;
long time3 = 0;
long time4 = 0;
long debounce1 = 200; // the debounce time, increase if the output flickers
long debounce2 = 200;
long debounce3 = 200;
long debounce4 = 200;
void setup()
{
pinMode(button1, INPUT);
pinMode(button2, INPUT);
pinMode(button3, INPUT);
pinMode(button4, INPUT);
pinMode(rl1, OUTPUT);
pinMode(rl2, OUTPUT);
pinMode(rl3, OUTPUT);
pinMode(rl4, OUTPUT);
}
void loop() {
reading1 = digitalRead(button1);
reading2 = digitalRead(button2);
reading3 = digitalRead(button3);
reading4 = digitalRead(button4);
// if the input just went from LOW and HIGH and we've waited long enough
// to ignore any noise on the circuit, toggle the output pin and remember
// the time
//Condition Relay 1
if (reading1 == HIGH && previous1 == LOW && millis() - time1 > debounce1) {
if (state1 == HIGH)
state1 = LOW;
else
state1 = HIGH;
time1 = millis();
}
//Condition Relay 2
if (reading2 == HIGH && previous2 == LOW && millis() - time2 > debounce2) {
if (state2 == HIGH)
state2 = LOW;
else
state2 = HIGH;
time2 = millis();
}
//Condition Relay 3
if (reading3 == HIGH && previous3 == LOW && millis() - time3 > debounce3) {
if (state3 == HIGH)
state3 = LOW;
else
state3 = HIGH;
time3 = millis();
}
//Condition Relay 4
if (reading4 == HIGH && previous4 == LOW && millis() - time4 > debounce4) {
if (state4 == HIGH)
state4 = LOW;
else
state4 = HIGH;
time4 = millis();
}
digitalWrite(rl1, state1);
digitalWrite(rl2, state2);
digitalWrite(rl3, state3);
digitalWrite(rl4, state4);
previous1 = reading1;
previous2 = reading2;
previous3 = reading3;
previous4 = reading4;
}
I'm trying to find a way to use one button to enable/disable commands. (actually, it's a multicolor LED i'm trying to start/stop changing colors)
My code is under here, but it does not work, if anyone could tell me what's wrong, i can't see it...
int red = 0;
int redPin = 9;
int blue = 0;
int bluePin = 11;
int green = 0;
int greenPin = 10;
int state = 0;
int stateModulo = 0;
void setup() {
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(9, OUTPUT);
pinMode(2, INPUT);
}
void checkButton(int var, int result) {
if (digitalRead(2) == HIGH) {
var++;
result = var%2;
}
}
void changecolor(int startColor,int endColor,int startPin,int endPin,int delayTime)
{
for (endColor = 0; endColor <= 255; endColor++)
{
checkButton(state,stateModulo);
if (stateModulo == 0) {
startColor = 255 - endColor;
analogWrite(endPin, endColor);
analogWrite(startPin, startColor);
delay(delayTime);
}
}
}
void loop() {
changecolor(red,green,redPin,greenPin,10);
changecolor(green,blue,greenPin,bluePin,10);
changecolor(blue,red,bluePin,redPin,10);
}
In the code below, result is not passed by reference, nor returned.
The same applies to var, after you have modified it you throw away any edit you have made.
void checkButton(int var, int result) {
if (digitalRead(2) == HIGH) {
var++;
result = var%2;
}
}
I can recommend you a good C++ book where to learn some language basics.
My suggestion: Thinking in C++, by Bruce Eckel.
Consider this:
//Buttons
int button1 = 7;
int button2 = 6;
int button3 = 4;
int button4 = 2;
//Relays
int rl1 = 13;
int rl2 = 12;
int rl3 = 11;
int rl4 = 8;
//States for Relay and Button (1)
int state1 = HIGH; // the current state of the output pin
int reading1; // the current reading from the input pin
int previous1 = LOW; // the previous reading from the input pin
//States for Relay and Button (2)
int state2 = HIGH; // the current state of the output pin
int reading2; // the current reading from the input pin
int previous2 = LOW; // the previous reading from the input pin
//States for Relay and Button (3)
int state3 = HIGH; // the current state of the output pin
int reading3; // the current reading from the input pin
int previous3 = LOW; // the previous reading from the input pin
//States for Relay and Button (4)
int state4 = HIGH; // the current state of the output pin
int reading4; // the current reading from the input pin
int previous4 = LOW; // the previous reading from the input pin
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time1 = 0; // the last time the output pin was toggled
long time2 = 0;
long time3 = 0;
long time4 = 0;
long debounce1 = 200; // the debounce time, increase if the output flickers
long debounce2 = 200;
long debounce3 = 200;
long debounce4 = 200;
void setup()
{
pinMode(button1, INPUT);
pinMode(button2, INPUT);
pinMode(button3, INPUT);
pinMode(button4, INPUT);
pinMode(rl1, OUTPUT);
pinMode(rl2, OUTPUT);
pinMode(rl3, OUTPUT);
pinMode(rl4, OUTPUT);
}
void loop() {
reading1 = digitalRead(button1);
reading2 = digitalRead(button2);
reading3 = digitalRead(button3);
reading4 = digitalRead(button4);
// if the input just went from LOW and HIGH and we've waited long enough
// to ignore any noise on the circuit, toggle the output pin and remember
// the time
//Condition Relay 1
if (reading1 == HIGH && previous1 == LOW && millis() - time1 > debounce1) {
if (state1 == HIGH)
state1 = LOW;
else
state1 = HIGH;
time1 = millis();
}
//Condition Relay 2
if (reading2 == HIGH && previous2 == LOW && millis() - time2 > debounce2) {
if (state2 == HIGH)
state2 = LOW;
else
state2 = HIGH;
time2 = millis();
}
//Condition Relay 3
if (reading3 == HIGH && previous3 == LOW && millis() - time3 > debounce3) {
if (state3 == HIGH)
state3 = LOW;
else
state3 = HIGH;
time3 = millis();
}
//Condition Relay 4
if (reading4 == HIGH && previous4 == LOW && millis() - time4 > debounce4) {
if (state4 == HIGH)
state4 = LOW;
else
state4 = HIGH;
time4 = millis();
}
digitalWrite(rl1, state1);
digitalWrite(rl2, state2);
digitalWrite(rl3, state3);
digitalWrite(rl4, state4);
previous1 = reading1;
previous2 = reading2;
previous3 = reading3;
previous4 = reading4;
}