ESP32 LoRa settings are not applied - c

I use this board from Heltec automation, which has LoRa and an OLED display onboard.
I do not use the Heltec library, instead I use the lora.h library directly.
When I want to adjust the spreading factor and transmitting power, these settings are not applied and there is no change in the signal. Also I have read different registers regarding spreading factor and transmitting power before and after setting and there is no change.
In summary, when I try this, nothing happens.
LoRa.setTxPower(20);
LoRa.setSpreadingFactor(12);
The code:
#include <Arduino.h>
#include <LoRa.h>
#include <Wire.h>
#include <SSD1306Wire.h>
SSD1306Wire display(0x3c, SDA_OLED, SCL_OLED, GEOMETRY_128_64);
const int csPin = 18; // LoRa radio chip select
const int resetPin = 14; // LoRa radio reset
const int irqPin = 26; // change for your board; must be a hardware interrupt pin
String outgoing; // outgoing message
byte msgCount = 0; // count of outgoing messages
byte localAddress = 0xBB; // address of this device
byte destination = 0xFF; // destination to send to
long lastSendTime = 0; // last send time
int interval = 2000; // interval between sends
int msgLoopCounter = 0;
void setup() {
Serial.begin(115200);
while (!Serial);
// Set OLED reset pin to HIGH
pinMode(RST_OLED, OUTPUT);
digitalWrite(RST_OLED, HIGH);
delay(1000);
// Initialze OLED display
if (!display.init()) {
display.setContrast(255);
display.clear();
display.display();
while (true);
}
Serial.println("Display init succeeded.");
// Initialize LoRa
LoRa.setPins(csPin, resetPin, irqPin); // set CS, reset, IRQ pin
LoRa.setTxPower(20);
LoRa.setSpreadingFactor(12);
if (!LoRa.begin(868E6)) {
Serial.println("LoRa init failed. Check your connections.");
while (true);
}
Serial.println("LoRa init succeeded.");
}
void sendMessage(String outgoing) {
LoRa.beginPacket(); // start packet
LoRa.write(destination); // add destination address
LoRa.write(localAddress); // add sender address
LoRa.write(msgCount); // add message ID
LoRa.write(outgoing.length()); // add payload length
LoRa.print(outgoing); // add payload
LoRa.endPacket(); // finish packet and send it
msgCount++; // increment message ID
}
void loop() {
if (millis() - lastSendTime > interval) {
String message = "HeLoRa!";
sendMessage(message);
Serial.println("Sending " + message);
lastSendTime = millis();
display.clear();
display.drawString(0, 0, String(lastSendTime));
display.display();
}
}
I also tried to set the values after LoRa.begin(), but then nothing is received by the receiver.
NOTE: It can't be the board itself, since I have several and have tried it with each one.

Related

How to update the LED on a TI board and report to the server every second via UART

I am modifying a code in embedded C language and trying to make it to where it checks buttons every 200ms, checks the temperature every 500ms, and update the LED and report to the server every second. My code appears to be complete but when I run it, nothing outputs to the console, and my LED light neither turns off or on when I press either buttons on the side of the TI board. Is there something wrong with my nested while loop? Here is my code:
/*
* ======== gpiointerrupt.c ========
*/
#include <stdint.h>
#include <stddef.h>
/* Driver Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/I2C.h>
#include <ti/drivers/UART.h>
/* Driver configuration */
#include "ti_drivers_config.h"
/* Driver timer */
#include <ti/drivers/Timer.h>
#define TRUE 1
#define FALSE 0
#define NUMBER_OF_TASKS 3
#define GLOBAL_PERIOD 100 //milliseconds
#define DISPLAY(x) UART_write(uart, &output, x);
// UART Global Variables
char output[64];
int bytesToSend;
// Driver Handles - Global variables
UART_Handle uart;
// Init variables
int buttonCheckTime = 0;
int tempCheckTime = 0;
int displayCheckTime = 0;
int buttonCheckPeriod = 200;
int tempCheckPeriod = 500;
int displayCheckPeriod = 1000;
int setpoint = 25;
int heat = 0;
int seconds = 0;
int temperature = 0;
int firstButtonWasPressed = FALSE; // It is initally false that the button was pressed
int secondButtonWasPressed = FALSE; // It is initally false that the button was pressed
int global_period = GLOBAL_PERIOD; // Global period to be used initTimer()
void initUART(void)
{
UART_Params uartParams;
// Init the driver
UART_init();
// Configure the driver
UART_Params_init(&uartParams);
uartParams.writeDataMode = UART_DATA_BINARY;
uartParams.readDataMode = UART_DATA_BINARY;
uartParams.readReturnMode = UART_RETURN_FULL;
uartParams.baudRate = 115200;
// Open the driver
uart = UART_open(CONFIG_UART_0, &uartParams);
if (uart == NULL)
{
/* UART_open() failed */
while (1)
;
}
}
// I2C Global Variables
static const struct
{
uint8_t address;
uint8_t resultReg;
char *id;
} sensors[3] = { { 0x48, 0x0000, "11X" }, { 0x49, 0x0000, "116" }, { 0x41,
0x0001,
"006" } };
uint8_t txBuffer[1];
uint8_t rxBuffer[2];
I2C_Transaction i2cTransaction;
// Driver Handles - Global variables
I2C_Handle i2c;
// Initialize the I2C peripheral
// Make sure you call initUART() before calling this function.
void initI2C(void)
{
int8_t i, found;
I2C_Params i2cParams;
DISPLAY(snprintf(output, 64, "Initializing I2C Driver - "))
// Init the driver
I2C_init();
// Configure the driver
I2C_Params_init(&i2cParams);
i2cParams.bitRate = I2C_400kHz;
// Open the driver
i2c = I2C_open(CONFIG_I2C_0, &i2cParams);
if (i2c == NULL)
{
DISPLAY(snprintf(output, 64, "Failed\n\r"))
while (1)
;
}
DISPLAY(snprintf(output, 32, "Passed\n\r"))
// Boards were shipped with different sensors.
// Welcome to the world of embedded systems.
// Try to determine which sensor we have.
// Scan through the possible sensor addresses
/* Common I2C transaction setup */
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount = 1;
i2cTransaction.readBuf = rxBuffer;
i2cTransaction.readCount = 0;
found = false;
for (i = 0; i < 3; ++i)
{
i2cTransaction.slaveAddress = sensors[i].address;
txBuffer[0] = sensors[i].resultReg;
DISPLAY(snprintf(output, 64, "Is this %s? ", sensors[i].id))
if (I2C_transfer(i2c, &i2cTransaction))
{
DISPLAY(snprintf(output, 64, "Found\n\r"))
found = true;
break;
}
DISPLAY(snprintf(output, 64, "No\n\r"))
}
if (found)
{
DISPLAY(snprintf(output, 64, "Detected TMP%s I2C address: %x\n\r",
sensors[i].id, i2cTransaction.slaveAddress))
}
else
{
DISPLAY(snprintf(output, 64,
"Temperature sensor not found, contact professor\n\r"))
}
}
int16_t readTemp(void)
{
int j;
int16_t temperature = 0;
i2cTransaction.readCount = 2;
if (I2C_transfer(i2c, &i2cTransaction))
{
/*
* Extract degrees C from the received data;
* see TMP sensor datasheet
*/
temperature = (rxBuffer[0] << 8) | (rxBuffer[1]);
temperature *= 0.0078125;
/*
* If the MSB is set '1', then we have a 2's complement
* negative value which needs to be sign extended
*/
if (rxBuffer[0] & 0x80)
{
temperature |= 0xF000;
}
}
else
{
DISPLAY(snprintf(output, 64, "Error reading temperature sensor (%d)\n\r", i2cTransaction.status))
DISPLAY(snprintf(output,64, "Please power cycle your board by unplugging USB and plugging back in.\n\r"))
}
return temperature;
}
// Driver Handles - Global variables
Timer_Handle timer0;
volatile unsigned char TimerFlag = 0;
// A single task in the task list.
struct task_entry
{
void (*f)(); // Function to call to perform the task
int elapsed_time; // Amount of time since last triggered
int period; // Period of the task in ms
char triggered; // Whether or not the task was triggered
};
// Forward declaration
void task_one();
void task_two();
void task_three();
void task_one()
{
// Processing for task_one takes place
/* Every 200ms, check button presses */
if (buttonCheckTime >= buttonCheckPeriod) // Button check time equals or exceeds period
{
if (firstButtonWasPressed == TRUE) // Button on one side raises setpoint (thermostat setting) by 1
{
setpoint += 1; // Increment thermostat
firstButtonWasPressed = FALSE; // Reset button to FALSE
}
if (secondButtonWasPressed == TRUE) // Button on the other side lowers setpoint (thermostat setting) by 1
{
setpoint -= 1; // Decrement thermostat
secondButtonWasPressed = FALSE; // Reset button to FALSE
}
}
}
void task_two()
{
// Processing for task_two takes place
if (tempCheckTime >= tempCheckPeriod) // Temperature check time equals or exceeds period
{
temperature = readTemp();
if (temperature > setpoint) {
GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF);
heat = 0;
}
else {
GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
heat = 1;
}
}
}
void task_three()
{
// Processing for task_three takes place
if (displayCheckTime == displayCheckPeriod) {
DISPLAY(snprintf(output, 64, "<%02d,%02d,%d,%04d>\n\r", temperature,
setpoint, heat, seconds));
++seconds;
}
}
// The task list
struct task_entry tasks[NUMBER_OF_TASKS] = { { FALSE, &task_one, 500, 500 }, {FALSE, &task_two, 1500, 1500 }, { FALSE, &task_three, 2000, 2000 } };
void timerCallback(Timer_Handle myHandle, int_fast16_t status)
{
int x = 0;
// Walk through each task.
for (x = 0; x < NUMBER_OF_TASKS; x++)
{
// Check if task's interval has expire
if (tasks[x].elapsed_time >= tasks[x].period)
{
// Bing! This task's timer is up
// Set it's flag, and the global flag
tasks[x].triggered = TRUE;
TimerFlag = TRUE;
// Reset the elapsed_time
tasks[x].elapsed_time = 0;
}
else
{
tasks[x].elapsed_time += global_period;
}
}
}
void initTimer(void)
{
Timer_Params params;
// Init the driver
Timer_init();
// Configure the driver
Timer_Params_init(&params);
params.period = 1000000;
params.periodUnits = Timer_PERIOD_US;
params.timerMode = Timer_CONTINUOUS_CALLBACK;
params.timerCallback = timerCallback;
// Open the driver
timer0 = Timer_open(CONFIG_TIMER_0, &params);
if (timer0 == NULL)
{
/* Failed to initialized timer */
while (1)
{
}
}
if (Timer_start(timer0) == Timer_STATUS_ERROR)
{
/* Failed to start timer */
while (1)
{
}
}
}
/*
* ======== gpioButtonFxn0 ========
* Callback function for the GPIO interrupt on CONFIG_GPIO_BUTTON_0.
*
* Note: GPIO interrupts are cleared prior to invoking callbacks.
*/
void gpioButtonFxn0(uint_least8_t index)
{
/* Toggle an LED */
//GPIO_toggle(CONFIG_GPIO_LED_0);
firstButtonWasPressed = TRUE; // It is true that the button was pressed
}
/*
* ======== gpioButtonFxn1 ========
* Callback function for the GPIO interrupt on CONFIG_GPIO_BUTTON_1.
* This may not be used for all boards.
*
* Note: GPIO interrupts are cleared prior to invoking callbacks.
*/
void gpioButtonFxn1(uint_least8_t index)
{
/* Toggle an LED */
//GPIO_toggle(CONFIG_GPIO_LED_1);
secondButtonWasPressed = TRUE;
}
/*
* ======== mainThread ========
*/
void* mainThread(void *arg0)
{
/* Call driver init functions */
GPIO_init();
/* Configure the LED and button pins */
GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
//GPIO_setConfig(CONFIG_GPIO_BUTTON_0;
//GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
/* Turn on user LED */
GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
/* Install Button callback */
GPIO_setCallback(CONFIG_GPIO_BUTTON_0, gpioButtonFxn0);
/* Enable interrupts */
GPIO_enableInt(CONFIG_GPIO_BUTTON_0);
/*
* If more than one input pin is available for your device, interrupts
* will be enabled on CONFIG_GPIO_BUTTON1.
*/
if (CONFIG_GPIO_BUTTON_0 != CONFIG_GPIO_BUTTON_1)
{
/* Configure BUTTON1 pin */
GPIO_setConfig(CONFIG_GPIO_BUTTON_1,
GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
/* Install Button callback */
GPIO_setCallback(CONFIG_GPIO_BUTTON_1, gpioButtonFxn1);
/* Enable interrupts */
GPIO_enableInt(CONFIG_GPIO_BUTTON_1);
}
// Call driver init functions
initUART(); // The UART must be initialized before calling initI2C()
initI2C();
initTimer();
// Loop Forever
while (TRUE)
{
readTemp();
// Every 200ms check the button flags
task_one();
// Every 500ms read the temperature and update the LED
task_two();
// Every second output the following to the UART
// "<%02d,%02d,%d,%04d>, temperature, setpoint, heat, seconds
task_three();
// Wait for task intervals (periods) to elapse
while (!TimerFlag)
{
} // Wait for timer period
// Process the tasks for which the interval has expired
int x = 0;
for (x = 0; x < NUMBER_OF_TASKS; x++)
{
if (tasks[x].triggered)
{
tasks[x].f();
// reset
tasks[x].triggered = FALSE;
}
}
// Reset everything (e.g. flags) and go back to the beginning
TimerFlag = FALSE; // Lower flag raised by timer
++global_period;
}
}

Cannot connect ClearCore and Kinco HMI

I have been working on this for almost 3 weeks now and cannot find a solution. I am trying to output information from my Teknic ClearCore to a Kinco HMI (GL070E) by ANY means. I have tried both Serial communication (RS232) and Ethernet (still lost on this but I attempted the modbus technique). below are some links to things I have tried for this. the best one seems to be the Tools40 modbus library, but clearcore doesn't support that i guess. please help.
https://github.com/IndustrialShields/arduino-Tools40
https://www.youtube.com/watch?v=W-7s52zUVng
https://www.youtube.com/watch?v=KRno6stglPk&list=PL10EF6AF38416A66F&index=4
below is my code and it's a mess because I'm panicking:
#include "ClearCore.h"
// Defines the analog input to control commanded velocity
#define Estop ConnectorDI8 //Estop
#define counter ConnectorIO2 //induction3
// Select the baud rate to match the target device.
#define baudRate 9600
int count = 0;
int d = 1;
int x = 0;
int r = 0;
void setup() {
// Put your setup code here, it will only run once:
// Sets up serial communication and waits up to 5 seconds for a port to open.
// Serial communication is not required for this example to run.
Serial.begin(baudRate);
uint32_t timeout = 5000;
uint32_t startTime = millis();
while (!Serial && millis() - startTime < timeout)
{
continue;
}
//Configure Serial communication to HMI.
// Configure COM-0 for RS-232 mode.
ConnectorCOM0.Mode(Connector::RS232);
// Set the data baud rate.
ConnectorCOM0.Speed(9600);
// (Optional) Set the data frame parity.
ConnectorCOM0.Parity(SerialBase::PARITY_E);
// (Optional) Set each data frame to use 2 stop bits.
ConnectorCOM0.StopBits(2);
// (Optional) Enable flow control.
//ConnectorCOM0.FlowControl(true);
// Open the serial port to enable data transmission.
ConnectorCOM0.PortOpen();
}
void loop() {
/****Reset circuit***************************************************************************************************/
if (ConnectorIO1.State()==HIGH && r == 1)
{
digitalWrite(IO0, true);
delay(300);
r = 0;
}
/****Estop circuit***************************************************************************************************/
while (ConnectorDI8.State()==LOW)
{
r = 1;
digitalWrite(IO0, false);
}
if (r==0)
{
Serial0.write(count);
Serial.println(count);
/****COUNTER*****************************************************************************************/
if (ConnectorIO2.State() == HIGH)
{
count++;
}
}
}

How to use a Switch to switch from Wifi Access Point mode to STA in esp32

I am doing an autonomous car project, I need manual control as well as an autonomous function, so the manual control is done through wifi using "gesture control" and for the autonomous control I want to send the location data via an HTTP request, but then I have to switch to an STA mode, so I want to use a Toggle switch connected to ground and a pin as input and put it in an "if statement", but all of the initial setups come in the void setup(), so I don't know how to proceed I have provided the AP part of the main code I am using
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#include <TinyGPS++.h> // Tiny GPS Plus Library
#define CHANNEL 4
uint8_t mac[] = {0x36, 0x33, 0x33, 0x33, 0x33, 0x33};
struct __attribute__((packed)) DataStruct {
//char text[32];
int x;
int y;
unsigned long time;
};
DataStruct myData;
//**********************************************
// GPS Locations
unsigned long Distance_To_Home; // variable for storing the distance to destination
int ac =0; // GPS array counter
int wpCount = 0; // GPS waypoint counter
double Home_LATarray[50]; // variable for storing the destination Latitude - Only Programmed for 5 waypoint
double Home_LONarray[50]; // variable for storing the destination Longitude - up to 50 waypoints
int increment = 0;
#define autopilot 13
void gesturecontroll();
void getGPS();
void getCompass();
void setWaypoint();
void move();
int blueToothVal;
void setup()
{ Serial.begin(9600); // Serial 0 is for communication with the computer
S2.begin(9600); // Serial 2 is for GPS communication at 9600 baud - DO NOT MODIFY - Ublox Neo 6m
Serial.println("ESPNow/Basic/Slave Example");
//Set device in AP mode to begin with
WiFi.mode(WIFI_AP);
// configure device AP mode
// This is the mac address of the Slave in AP Mode
esp_wifi_set_mac(ESP_IF_WIFI_STA, &mac[0]);
Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
// Init ESPNow with a fallback logic
if (esp_now_init()!=0) {
Serial.println("*** ESP_Now init failed");
while(true) {};
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info.
esp_now_register_recv_cb(OnDataRecv);
Serial.print("Aheloiioi");
// Extras////////////////////////////////////////////////////////////////////////////////////
pinMode(autopilot, INPUT);
}
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) {
memcpy(&myData, data, sizeof(myData));
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.print("Last Packet Recv from: "); Serial.println(macStr);
Serial.print("Last Packet Recv Data: ");
Serial.println(myData.x);
Serial.println(myData.y);
Serial.println("");
Serial.println();
//move();
Serial.println();
}
//********************************************************************************************************
// Main Loop
void loop()
{ if (autopilot == HIGH)
{
// going for manual control, BUT WHAT SHOULD I PUT HERE?
}
else
{
getGPS(); // Update the GPS location
getCompass(); // Update the CompaSerial Heading
Ping(); // Use at your own discretion, this is not fully tested
}
}

HAL_UART_Transmit_IT sending data twice

I am trying to establish UART communication between a PC and a STM32f407-DISC1 board using an arduino nano as a middle man.
The PC sends 'r' to the arduino to indicate a request.
The request is then communicated to the stm32 with a GPIO interrupt, which then should be transmitting 480 bytes of data using HAL_UART_Transmit_IT.
It however sends the data twice, with only a single request made.
The code on the STM32 is generated by STM32CubeMX
Data request made by the arduino
void loop() {
digitalWrite(4, 0); // Clear EXTI11 line.
if (mySerial.available() && received < 480) { // STM32 sending data and is not done.
buff[received] = mySerial.read(); // Append received data to the buffer.
received++;
}
if (received >= 480) { // If the buffer is full
received = 0; // transmit it to PC.
Serial.println(buff);
}
if (Serial.available()) {
if (Serial.read() == 'r') { // PC requests data from the STM32
digitalWrite(4, 1); // Triggers STM32 EXTI11 line.
while (Serial.available()) // Empty the buffer.
Serial.read();
}
}
}
data transmission on the STM32
void EXTI15_10_IRQHandler(void)
{
// Make sure that the interrupt is the good one.
if (HAL_GPIO_ReadPin(data_req_IRQ_GPIO_Port, data_req_IRQ_Pin)) {
if (is_sending_data == FALSE) // If no transmission is happening
should_send_data = TRUE; // raise transmission flag.
}
// IRQ handling stuff...
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart) {
is_sending_data = FALSE; // Transmition is completed, unblock requests.
}
void main(void){
// Init and other stuff...
while (1) {
if (should_send_data == TRUE) { // If data was requested
HAL_GPIO_WritePin(LD5_GPIO_Port, LD5_Pin, GPIO_PIN_RESET);
HAL_UART_Transmit_IT(&huart3, matrice, 480); // Start transmission by interrupt.
is_sending_data = TRUE; // Block requests.
should_send_data = FALSE; // Clear flag.
}
// matrice acquisition stuff here
}
}
Alright so I found a solution, but it involved just rethinking my approach, so sorry for those looking for an answer to this problem.
I removed the arduino middle man by replacing it with a USB to RS232 converter and made UART reception work by interrupt. The STM detects the 'r' character which triggers the data communication.
Here is the interrupt part:
void USART3_IRQHandler(void)
{
if (USART3->SR & UART_IT_RXNE) { // If a byte is received
rxBuff[0] = (uint8_t) (huart3.Instance->DR & (uint8_t) 0xFF); // Read it.
__HAL_UART_FLUSH_DRREGISTER(&huart3); // Clear the buffer to avoid errors.
rx_new_char_flag = TRUE; // Raise the new_char flag.
return; // Stops the IRQHandler from disabling interrupts.
}
}
and the gestion of that in the main
while (1) {
if (rx_new_char_flag == TRUE) {
rx_new_char_flag = FALSE;
if (rxBuff[0] == 'r') {
rxBuff[0] = 0;
HAL_UART_Transmit_IT(&huart3, matrice, 480); // Start transmission by interrupt.
}
}
On the PC side, to optimize performance, instead of waiting for the full 480 bytes, I wait for only one character, if one is received I keep reading the serial port, as shown in the code bellow
int i = 0;
do {
ReadFile(m_hSerial, &temp_rx[i], 1, &dwBytesRead, NULL);
i++;
} while (dwBytesRead > 0 && i < 480);
for (int j = i; j < 480; j++) // If the transmission is incomplete, fill the buffer with 0s to avoid garbage data.
temp_rx[j] = 0;
if(i>=480) // If all the bytes has been received, copy the data in the working buffer.
std::copy(std::begin(temp_rx), std::end(temp_rx), std::begin(m_touch_state));
This works well with pretty decent performance, so that may be a permanent solution to my problem.

arduino uno IR receiver motor control

Hi I'm new and have had a bit of a search for a solution to this problem, but is appears to be unique.
I have an arduino uno and I want to control multiple dc motors speeds and directions with it wirelessly with an IR remote. I have managed to attach a motor and get the arduino to turn it on by pressing a button on the remote control, however I cannot get it to turn off by pressing another button. What happens is when I open the serial monitor for the arduino, it recognises the first IR signal and turns the motor on. However when the motor is spinning (and only when the motor is spinning) the arduino detects an endless stream of IR signals which stop the arduino from receiving any real ones. This occurs even when the IR receiver is pulled out of the circuit. I am using the analogWrite() function to turn the motor on and if I lower the pulse enough that the motor doesn't turn (but makes a noise) it can be started and stopped with the remote because it doesn't turn and therefore doesn't make the arduino receive IR signals. If I make the pulse low enough that I can forcibly stop the motor, the IR signals stop.
I have no idea what is happening and have tried altering my code and the circuits.
Here is the code I am using - I copied and modified one from adafruit which reads IR commands.
/* Raw IR commander
This sketch/program uses the Arduno and a PNA4602 to
decode IR received. It then attempts to match it to a previously
recorded IR signal
Code is public domain, check out www.ladyada.net and adafruit.com
for more tutorials!
*/
// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!
//uint8_t IRpin = 2;
// Digital pin #2 is the same as Pin D2 see
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
#define IRpin_PIN PIND
#define IRpin 2
// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000
#define NUMPULSES 50
// what our timing resolution should be, larger is better
// as its more 'precise' - but too large and you wont get
// accurate timing
#define RESOLUTION 20
// What percent we will allow in variation to match the same code
#define FUZZINESS 20
// we will store up to 100 pulse pairs (this is -a lot-)
uint16_t pulses[NUMPULSES][2]; // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing
#include "own_codes.h"
int numberpulses = 0;
int a;
void setup(void) {
Serial.begin(9600);
Serial.println("Ready to decode IR!");
}
void loop(void) {
numberpulses = listenForIR();
Serial.print("Heard ");
Serial.print(numberpulses);
Serial.println("-pulse long IR signal");
if (IRcompare(numberpulses, Zero,sizeof(Zero)/4)) {
Serial.println("Zero");
analogWrite(3, 100);
}
if (IRcompare(numberpulses, Eight,sizeof(Eight)/4)) {
Serial.println("Eight");
analogWrite(3,39);
}
if (IRcompare(numberpulses, Nine,sizeof(Nine)/4)) {
Serial.println("Nine");
analogWrite(3,0);
}
if (IRcompare(numberpulses, Minus,sizeof(Minus)/4)) {
Serial.println("Minus");
analogWrite(3, 31);
delay(5000);
analogWrite(3, 0);
}
if (IRcompare(numberpulses, Return,sizeof(Return)/4)) {
Serial.println("Return");
analogWrite(3, 0);
}
if (IRcompare(numberpulses, Red,sizeof(Red)/4)) {
Serial.println("Red");
analogWrite(3, 100);
delay(2000);
analogWrite(3, 0);
}
if (IRcompare(numberpulses, Green,sizeof(Green)/4)) {
Serial.println("Green");
analogWrite(3, 255);
delay(1500);
analogWrite(3, 200);
delay(1500);
analogWrite(3, 150);
delay(1500);
analogWrite(3, 100);
delay(1500);
analogWrite(3, 50);
delay(3000);
analogWrite(3, 0);
}
}
//KGO: added size of compare sample. Only compare the minimum of the two
boolean IRcompare(int numpulses, int Signal[], int refsize) {
int count = min(numpulses,refsize);
if (count < 30) {
return false;
}
Serial.print("count set to: ");
Serial.println(count);
for (int i=0; i< count-1; i++) {
int oncode = pulses[i][1] * RESOLUTION / 10;
int offcode = pulses[i+1][0] * RESOLUTION / 10;
#ifdef DEBUG
Serial.print(oncode); // the ON signal we heard
Serial.print(" - ");
Serial.print(Signal[i*2 + 0]); // the ON signal we want
#endif
// check to make sure the error is less than FUZZINESS percent
if ( abs(oncode - Signal[i*2 + 0]) <= (Signal[i*2 + 0] * FUZZINESS / 100)) {
#ifdef DEBUG
Serial.print(" (ok)");
#endif
} else {
#ifdef DEBUG
Serial.print(" (x)");
#endif
// we didn't match perfectly, return a false match
return false;
}
#ifdef DEBUG
Serial.print(" \t"); // tab
Serial.print(offcode); // the OFF signal we heard
Serial.print(" - ");
Serial.print(Signal[i*2 + 1]); // the OFF signal we want
#endif
if ( abs(offcode - Signal[i*2 + 1]) <= (Signal[i*2 + 1] * FUZZINESS / 100)) {
#ifdef DEBUG
Serial.print(" (ok)");
#endif
} else {
#ifdef DEBUG
Serial.print(" (x)");
#endif
// we didn't match perfectly, return a false match
return false;
}
#ifdef DEBUG
Serial.println();
#endif
}
// Everything matched!
return true;
}
int listenForIR(void) {
currentpulse = 0;
while (1) {
uint16_t highpulse, lowpulse; // temporary storage timing
highpulse = lowpulse = 0; // start out with no pulse length
// while (digitalRead(IRpin)) { // this is too slow!
while (IRpin_PIN & (1 << IRpin)) {
// pin is still HIGH
// count off another few microseconds
highpulse++;
delayMicroseconds(RESOLUTION);
// If the pulse is too long, we 'timed out' - either nothing
// was received or the code is finished, so print what
// we've grabbed so far, and then reset
// KGO: Added check for end of receive buffer
if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
return currentpulse;
}
}
// we didn't time out so lets stash the reading
pulses[currentpulse][0] = highpulse;
// same as above
while (! (IRpin_PIN & _BV(IRpin))) {
// pin is still LOW
lowpulse++;
delayMicroseconds(RESOLUTION);
// KGO: Added check for end of receive buffer
if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
return currentpulse;
}
}
pulses[currentpulse][2] = lowpulse;
// we read one high-low pulse successfully, continue!
currentpulse++;
}
}
void printpulses(void) {
Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
for (uint8_t i = 0; i < currentpulse; i++) {
Serial.print(pulses[i][0] * RESOLUTION, DEC);
Serial.print(" usec, ");
Serial.print(pulses[i][3] * RESOLUTION, DEC);
Serial.println(" usec");
}
// print it in a 'array' format
Serial.println("int IRsignal[] = {");
Serial.println("// ON, OFF (in 10's of microseconds)");
for (uint8_t i = 0; i < currentpulse-1; i++) {
Serial.print("\t"); // tab
Serial.print(pulses[i][4] * RESOLUTION / 10, DEC);
Serial.print(", ");
Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
Serial.println(",");
}
Serial.print("\t"); // tab
Serial.print(pulses[currentpulse-1][5] * RESOLUTION / 10, DEC);
Serial.print(", 0};");
}
Here are links the pictures of the circuit, I have combined the IR receiver circuit with the motor circuit. (I'm not allowed to post images directly)
IR receiver: https://learn.adafruit.com/system/assets/assets/000/000/555/medium800/light_arduinopna4602.gif?1396763990
Motor circuit:
http://cdn.instructables.com/F9L/KDFG/GU7FXUMH/F9LKDFGGU7FXUMH.MEDIUM.jpg
Any help would be much appreciated thank you.
Here are some information about motor interference:
http://forum.allaboutcircuits.com/threads/stop-noise-from-motor-to-arduino-mcu.90733/
http://forum.arduino.cc/index.php?topic=60247.0

Resources