I have an Arduino with a RFid click board from Mikro Electronika. The click board has a microcontroller CR95HF microcontroller. According to the datasheet when I send the ECHO command I should poll and then read the returned value 0x55. If I use the command IDN (0x01) and send a datalength of zero, I should get the ID of the controller back.
According to the serial monitor it only returns zero (is there something wrong with the variable?).
According to the logic analyzer it returns the exact same thing as what was send
(when I send 3, it returns 3, when i send 55, it returns 55).
It seems the microcontroller doesn't react anything I send it or it does and it's just broken?
So right now it looks like it is able to send something through the spi.transfer() function, but the retrieve seems to be a problem.
Here's my code:
#include <SPI.h>
// CR95HF: Write, poll, read, reset
#define CMD 0x00
#define POLL 0x03
#define READ 0x02
#define RESET 0x01
#define ECHO 0x55
const int _SSpin = 10; // CS
const int _IRQpin = 6; // INT_out : 2, INT_in : 6, tried both, barely to no difference
//const int _SI0pin = A3;
//const int _SI1pin = A0;
void WakeupCR95HF()
{
//Serial.println("Wake up!");
digitalWrite(_IRQpin, LOW);
delay(100);
digitalWrite(_IRQpin, HIGH);
delay(100);
}
bool EchoResponse()
{
byte len = 0;
// write to CR95HF
digitalWrite(_SSpin, LOW);
delay(100);
SPI.transfer(0x00);
// Serial.print("echo code: ");
// Serial.println(ECHO);
SPI.transfer(0x55);
//SPI.transfer(0x00);
digitalWrite(_SSpin, HIGH);
//delay(1000);
// poll to CR95HF, is it ready?
byte tmp = 0;
digitalWrite(_SSpin, LOW);
while (!tmp)
{
delay(100);
//Note: whatever I send, I get the same thing back. I send 3, then tmp is 3. I send 8, tmp is 8.
SPI.transfer(0x03);
tmp = SPI.transfer(0);
// Serial.print("Polling: ");
Serial.println(tmp, BIN);
tmp = (tmp & 0x08) >> 3;
delay(100);
}
digitalWrite(_SSpin, HIGH);
delay(20);
// ready to write
byte res = 0;
digitalWrite(_SSpin, LOW);
delay(100);
SPI.transfer(0x02);
res = SPI.transfer(0);
// Serial.print("reading: ");
// Serial.println(res);
delay(100);
digitalWrite(_SSpin, HIGH);
delay(100);
if (res == ECHO)
{
return true;
}
return false;
}
void setup() {
Serial.begin(9600);
// I believe this is not possible on Arduino or not nessaccery, tried it anyway, no change
// pinMode(_SI0pin, OUTPUT);
// pinMode(_SI1pin, OUTPUT);
pinMode(_SSpin, OUTPUT);
pinMode(_IRQpin, OUTPUT);
// digitalWrite(_SI0pin, HIGH);
// digitalWrite(_SI1pin, LOW);
digitalWrite(_IRQpin, HIGH); // wakeup
delay(20);
digitalWrite(_SSpin, HIGH); // slave select, low = ready to write/read
delay(20);
SPI.begin();
// 2 MHz max clock speed, Most Significant Bit first, SPI_MODE unknown (probably 0, all were tried)
SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
WakeupCR95HF();
while(!EchoResponse())
{
WakeupCR95HF();
}
// Serial.println("Connection established");
}
void loop() {
}
Related
i am trying to make a program that turns on ,off and blinks an led with the help from bluetooth
On and of were pretty easy to replicate,but i can't make the blink to work.There are to options either blinks once,either if i ad a while it never stops from looping.i tried with both if and case.Can somebody help me.I am using an esp32.
The code with if:
#include "BluetoothSerial.h"
#include <Arduino.h>
#include <analogWrite.h>
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
int received;// received value will be stored in this variable
char receivedChar;// received value will be stored as CHAR in this variable
const char turnON ='a';
const char turnOFF ='b';
const char turnBLINK= 'c';
//const char turnFADE='d';
const int LEDpin = 12;
//int brightStep = 1;
//int brightness = 0;
void setup() {
Serial.begin(115200);
SerialBT.begin("Mono"); //Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
Serial.println("To turn ON send: a");//print on serial monitor
Serial.println("To turn OFF send: b"); //print on serial monitor
pinMode(LEDpin, OUTPUT);
// analogWriteResolution(LEDpin, 12);
}
void loop() {
receivedChar =(char)SerialBT.read();
if (Serial.available()) {
SerialBT.write(Serial.read());
}
if (SerialBT.available()) {
// while(SerialBT.available()){
// receivedChar =(char)SerialBT.read();
// }
SerialBT.print("Received:");// write on BT app
SerialBT.println(receivedChar);// write on BT app
Serial.print ("Received:");//print on serial monitor
Serial.println(receivedChar);//print on serial monitor
//SerialBT.println(receivedChar);//print on the app
//SerialBT.write(receivedChar); //print on serial monitor
if(receivedChar == turnON)
{
SerialBT.println("LED ON:");// write on BT app
Serial.println("LED ON:");//write on serial monitor
digitalWrite(LEDpin, HIGH);// turn the LED ON
}
if(receivedChar == turnOFF)
{
SerialBT.println("LED OFF:");// write on BT app
Serial.println("LED OFF:");//write on serial monitor
digitalWrite(LEDpin, LOW);// turn the LED off
}
if(receivedChar == turnBLINK)
{
SerialBT.println("LED blink:");// write on BT app
Serial.println("LED blink:");//write on serial monitor
while (receivedChar == turnBLINK){
//receivedChar =(char)SerialBT.read();
//if(receivedChar != turnBLINK){
// break;
// } else {
digitalWrite(LEDpin, HIGH);// turn the LED off
delay(1000);
digitalWrite(LEDpin,LOW);
delay(1000);
if(receivedChar != turnBLINK){
break; }
}
}
}
delay(20);
}
and with case:
#include "BluetoothSerial.h"
#include <Arduino.h>
#include <analogWrite.h>
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
int received;// received value will be stored in this variable
char receivedChar;// received value will be stored as CHAR in this variable
char data;
int option;
int blink=0;
const int LEDpin = 12;
void setup() {
Serial.begin(115200);
SerialBT.begin("Mono"); //Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
Serial.println("To turn ON send: 1");//print on serial monitor
Serial.println("To turn OFF send: 0"); //print on serial monitor
pinMode(12, OUTPUT);
}
void loop(){
receivedChar =(char)SerialBT.read();
// if (Serial.available()) {
// SerialBT.write(Serial.read());
// }
if (SerialBT.available()) {
// while(SerialBT.available()){
// receivedChar =(char)SerialBT.read();
// }
SerialBT.print("Received:");// write on BT app
SerialBT.println(receivedChar);// write on BT app
Serial.print ("Received:");//print on serial monitor
Serial.println(receivedChar);//print on serial monitor
//SerialBT.println(receivedChar);//print on the app
//SerialBT.write(receivedChar); //print on serial monitor
data=receivedChar;
if(data == '0')
{
option = 0;
blink=0;
}else if(data == '1')
{
option = 1;
blink=0;
}else if(data == '2')
{
option = 2;
blink=1;
}
switch (option)
{
case 0: // LED OFF
digitalWrite(LEDpin, LOW);
break;
case 1: //LED ON
digitalWrite(LEDpin, HIGH);
break;
case 2:
while(blink=1){// LED BLINK
digitalWrite(LEDpin , HIGH);
delay(200);
digitalWrite(LEDpin, LOW);
delay(200);
}
break;
}
}
}
First of all, you should clean your code to a minimum reproducible example. Remove all unnecessary comments and pieces of code that do not represent the main problem you are facing.
After a quick skim over your code, I immediately noticed this:
while(blink=1){// LED BLINK
digitalWrite(LEDpin , HIGH);
delay(200);
digitalWrite(LEDpin, LOW);
delay(200);
}
where it should be while(blink==1){ } --> very common mistake. This should be a comparison, NOT an assignment.
Now, you mention that it never stops running. Even after correcting the error I just pointed at, what part inside of your while loop breaks the logic of blink from being equal to 1? Otherwise, the while-loop will never stop
Finally, do not read the serial data inside the main loop(). Use SerialEvent, rather.
Again, it is quite tricky to follow the flow of your code. I suggest you divide your code into functions in order to make it more readable.
I am finishing up a project for school, and I am at the last step for getting my device 100% working. For a little information on the project. I am developing a wireless speedometer that tracks rpm and converts it to MPH through a hall effects sensor. The modules I am using Heltec LoRa esp32 in addition to the LoRa library through Arduino. The issue I am having is that I am trying to use the data packets received and use the sensor values sent out to be used in an if statement to activate a vibration motor to indicate if they reached a certain top speed. My code is below, and any input on how to use the packets correctly would be much appreciated. Thank you.
Receiver:
//lora stuff
#include <SPI.h>
#include <LoRa.h>
#include "SSD1306.h"
SSD1306 display(0x3c, 4, 15);
#define SS 18
#define RST 14
#define DI0 26
#define BAND 433E6
//neopixel
#include <Adafruit_NeoPixel.h>
#define LED_PIN 32
#define LED_COUNT 1
Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, 32, NEO_GRB + NEO_KHZ800);
const int buttonPin = 17;// button
const int neo = 32; //
const int neoCount = 1; //number of pixels
int counter = 0; //button state counter
int buttonState = 0;
//Vibration motor
int motorPin = 25;
//level of speed in mph to trigger motor
int beginner = 10;
int intermediate = 15;
int expert = 25;
int mphVal = 0;
String data;
unsigned int totalMPH;
void setup() {
//lora
pinMode(16, OUTPUT);
digitalWrite(16, LOW); // set GPIO16 low to reset OLED
delay(50);
digitalWrite(16, HIGH);
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
// button
pinMode(buttonPin, INPUT);
//motor
pinMode(motorPin, OUTPUT);
//neopixel
strip.begin();
strip.show();
strip.setBrightness(50);
Serial.begin(115200);
//lora initial
while (!Serial); //if just the the basic function, must connect to a computer
delay(100);
Serial.println("Speed Receiver");
display.drawString(5, 5, "Speed Receiver");
display.display();
SPI.begin(5, 19, 27, 18);
LoRa.setPins(SS, RST, DI0);
if (!LoRa.begin(BAND)) {
display.drawString(5, 25, "Starting LoRa failed!");
while (1);
}
Serial.println("LoRa Initial OK!");
display.drawString(5, 25, "LoRa Initializing OK!");
display.display();
}
void loop() {
// try to parse packet
int packetSize = LoRa.parsePacket();
if (packetSize) {
// received a packets
//Serial.print("Received packet. ");
display.clear();
display.setFont(ArialMT_Plain_16);
display.drawString(3, 0, "Received Speed ");
display.display();
// read packet
while (LoRa.available()) {
String data = LoRa.readString();
Serial.print(data);
display.drawString(20, 22, data);
display.display();
// if speed reaches x then motor will buzz
if (data.equals("MPH: 12.5")) {
digitalWrite(motorPin, HIGH);
delay(10);
digitalWrite(motorPin, LOW);
delay(10);
}
}
// print RSSI of packet
//Serial.print(" with RSSI ");
//Serial.println(LoRa.packetRssi());
// display.drawString(20, 45, "RSSI: ");
// display.drawString(70, 45, (String)LoRa.packetRssi());
// display.display();
}
//taking the packet and turning it into an int from string
//String data = data.toInt();
//int data = totalMPH;
//float totalMPH = data.toFloat();
// char data;
// float totalMPH;
//totalMPH = atof(data);
//Serial.println(totalMPH);
//button
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
counter++;
delay(150);
}
//button states with three colors
//beginner
else if (counter == 0) {
//Serial.println("pushed");
strip.setPixelColor(0, 255, 0, 0);
strip.show();
//Serial.println(0);
display.drawString(10, 45, "REC: 10 MPH");
display.display();
//vibration motor will trigger if the speed recieved is less then or equal to 12mph
// digitalWrite(motorPin, HIGH);
// delay(4000);
// digitalWrite(motorPin, LOW);
// delay(120000);
}
//intermediate
else if (counter == 1) {
strip.setPixelColor(0, 0, 255, 0);
strip.show();
Serial.println(1);
display.drawString(10, 45, "REC: 15 MPH");
display.display();
//vibration motor will trigger if the speed recieved is less then or equal to 17mph
// digitalWrite(motorPin, HIGH);
// delay(4000);
// digitalWrite(motorPin, LOW);
// delay(240000);
//digitalWrite(motorPin, LOW);
}
//expert
else if (counter == 2) {
strip.setPixelColor(0, 0, 0, 255);
strip.show();
Serial.print(2);
display.drawString(10, 45, "REC: 20 MPH");
display.display();
//digitalWrite(motorPin, LOW);
}
//reset settings
else {
counter = 0;
}
}
Transmitter:
//lora
#include <SPI.h>
#include <LoRa.h>
#include "SSD1306.h"
#include <Arduino.h>
#include <Bounce2.h>
Bounce hall = Bounce();
SSD1306 display(0x3c, 4, 15);
#define SS 18
#define RST 14
#define DI0 26
#define BAND 433E6 //915E6
int counter = 0;
int rpmTimer = 0;
int rpmInterval = 1000;
void setup() {
//board and lcd
pinMode(25, OUTPUT); //Send success, LED will bright 1 second
pinMode(16, OUTPUT);
digitalWrite(16, LOW); // set GPIO16 low to reset OLED
delay(50);
digitalWrite(16, HIGH);
// sensor and led
hall.attach(37, INPUT);
hall.interval(1);
//pinMode(led, OUTPUT);
//pinMode(hallSens, INPUT);
Serial.begin(115200);
//lcd
while (!Serial); //If just the the basic function, must connect to a computer
// Initialising the UI will init the display too.
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(5, 5, "LoRa Sender");
display.display();
//lora
SPI.begin(5, 19, 27, 18);
LoRa.setPins(SS, RST, DI0);
Serial.println("LoRa Sender");
if (!LoRa.begin(BAND)) {
Serial.println("Starting LoRa failed!");
while (1);
}
Serial.println("LoRa Initial OK!");
display.drawString(5, 20, "LoRa Initializing OK!");
display.display();
delay(10);
}
void loop() {
hall.update();
if(hall.rose()){
counter++;
}
if(millis() - rpmTimer > rpmInterval){
float rpm = counter * 60;
float rph = rpm * 60;
float dia = 0.00004349;
float cir = dia * 3.14;
float totalMPH = rph * cir;
Serial.println(totalMPH);
rpmTimer = millis();
counter = 0;
//sending packet
LoRa.beginPacket();
LoRa.print("MPH: " + String(totalMPH));
LoRa.endPacket();
//LoRa.sleep(); //puts lora receiver to sleep probably dont need
digitalWrite(25, HIGH); // turn the LED on (HIGH is the voltage level)
delay(10); // wait for a second
digitalWrite(25, LOW); // turn the LED off by making the voltage LOW
delay(100); // wait for a second
//delay(300);
}
}
In terms of wire-based API design:
// packet is the packet from the transmitter
String packet = "S12.5"
String measurement = packet.substring(0, 1); // "S"
if (measurement == "S") {
// at this point we know that the rest of the message is the MPH
String data = packet.substring(1, strlen(packet)-1); // "12.5"
float mph = data.toFloat();
if (mph >= TOP_SPEED) {
doSomething();
}
else {
doSomethingElse();
}
}
you could use charAt(0) to get the measurement instead of substring() if you know there are less than 25 sensors on the network.
each measurement would have its own char at the start of message and the data that related to that measurement would immediately follow. The sender and receiver are therefore interacting like a client/server in an API exchange. There is an implicit contract between them such that, when the transmitter says "S12.5", the receiver knows that means 12.5MPH. It's your system so you can design the communication packets any way you like.
I want to make the Arduino Pro Mini run on a 3.7v (4.2v when fully charged) LI-Ion battery.
The project is I will use an IR sensor to control the relay. Based on the IR code received, I will toggle the relay digital output pin (HIGH or LOW). Initially, the arduino is set to deep sleep mode and when it receives an External Interrupt (pin 2 on pro-mini), it will process the IR code and switch on the relay.
//Interrupts using Arduino
//Circuit Digest
#include "LowPower.h"
#include <IRremote.h>
volatile int output = LOW;
int i = 0;
#define RECV_PIN 2
volatile boolean sleepEnabled = true;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
irrecv.enableIRIn();
pinMode(RECV_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(RECV_PIN), buttonPressed1, RISING); // function for creating external interrupts at pin2 on Rising (LOW to HIGH)
}
void loop()
{
Serial.println(i);
++i;
delay(1000);
output = LOW;
digitalWrite(13, output); //Turns LED ON or OFF depending upon output value
if (sleepEnabled == true) {
Serial.println("Going to sleep");
delay(1000);
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
}
delay(500);
readIR();
}
void buttonPressed1() //ISR function excutes when push button at pinD2 is pressed
{
sleepEnabled = false;
}
void readIR() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
if (results.value == 0xff4ab5) {
sleepEnabled = true;
}
}
irrecv.resume(); // Receive the next value
}
When the pro-mini goes back to sleep, everything is turned off.
How can I make the pro-mini consume minimal power while the relay pin is HIGH ?
I have a simple setup with two Arduinos and a 433MHz transmitter and a receiver module.
The transmitter is set to transmit a string on button press, that side works correctly.
On the receiver end I have a simple program that's just writing whatever it's receiving to serial:
#include "VirtualWire.h"
int rx_pin = 2;
void setup(){
Serial.begin(9600);
Serial.println("serial ready");
vw_set_rx_pin(rx_pin);
vw_setup(2000);
vw_rx_start();
Serial.println("receiver ready");
}
void loop(){
uint8_t msg[VW_MAX_MESSAGE_LEN];
uint8_t msglen = VW_MAX_MESSAGE_LEN;
vw_wait_rx();
if(vw_get_message(msg, &msglen)){
Serial.print("Got: ");
for (int i = 0; i < msglen; i++)
{
Serial.print(char(msg[i]));
}
Serial.println();
}
}
When I then monitor serial, the receiving Arduino seems to receive the message twice each time it's sent. I used an oscilloscope to verify (to the best of my knowledge) that the transmitter is only sending the message once, I also tried wiring the two Arduinos together to make sure the issue is not with the RF modules, I got the same results.
This makes me think there is an issue with my code or with VirtualWire itself.
I'm thinking that I should somehow check if I've received the same message already or I should clear VirtualWire's buffer, how would I do either of those?
EDIT:
Here is the transmitter code:
#include "VirtualWire.h"
int tx_pin =2;
int interruptPin = 3;
volatile bool transmitBool = false;
void setup(){
vw_set_tx_pin(tx_pin);
vw_setup(2000);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), transmit, LOW);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
transmitBool = false;
}
void loop(){
if(transmitBool) {
transmitBool = false;
digitalWrite(13, HIGH);
vw_send((uint8_t *)"abc", 4);
vw_wait_tx();
delay(500);
digitalWrite(13, LOW);
}
}
void transmit() {
transmitBool = true;
}
I am trying to make a alarm clock with the raspberry pi and an arduino. I have been having this problem that when i use serial communication to send a number it, the lcd doesnt print the number. I know that the arduino is getting the number, for some reason it just wont print it. It instead prints weird symbols and lines. This article shows how i use serial communication between themThis is my arduino code.
#include <LiquidCrystal.h>
const int ledPin = 13;
LiquidCrystal lcd(12,11,5,4,3,2);
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
lcd.begin(16,2);
lcd.setCursor(0,1);
lcd.print("crystralball");
}
void loop()
{
if (Serial.available())
{
flash(Serial.read() - '0');
}
delay(1000);
}
void flash(int n)
{
for (int i = 0; i < n; i++)
{
digitalWrite(ledPin, HIGH);
lcd.clear();
lcd.write(n);
Serial.print(n);
Serial.flush();
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
}
}
Hi try to change your code in loop like this.
for (int i = 0; i < n; i++){
digitalWrite(ledPin, HIGH);
lcd.clear();
lcd.print(String(n));
Serial.print(n);
Serial.flush();
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
}
You have to use the method print and passing a string.