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++;
}
}
}
Related
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.
I've attached an image showing my oscilloscope readout which is from the code below. Context: I have a Pi and a PIC which need to communicate through UART connection. I've implemented my own flow control which can be seen in the image attached [RTS = Yellow Trace, CTS = Blue Trace, Rx = Green Trace]. The code runs through and is caught in the final switch case statement which turns on an LED. But when i debug the code, no values (well the only value which is read is zero) are read in. At first i thought that i'd configured my PIC clock wrong (which is used to derive the baud rate), but i don't think this is the case. Second i through the FIFO buffer was full of zeros only and considering that i'm sending only four packets of information to the PIC, and my FIFO is 4 registers deep that this was the reason why non of the information was appearing. So i executed a code which removes the dummy bytes but this did not work.
All that is received:
0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0><0> etc
I got the right settings selected: baud rate: 9600 data bits: 8 parity: none stop bits: 1
If anyone is willing to spend some time looking at my code, can you see any obvious errors?
https://i.stack.imgur.com/aQoAL.jpg
Minimum Reproducible Example
# include <xc.h>
# include <math.h>
# include <stdio.h>
# include <stdio.h>
//Configuration Bits
#pragma config FNOSC = FRCPLL // Internal Fast RC Oscillator (8MHz)
#pragma config FPLLIDIV = DIV_2 // Divide FRC before PLL (Now 4MHz)
#pragma config FPLLMUL = MUL_20 // PLL Multiply (Now 80MHz)
#pragma config FPLLODIV = DIV_2 // Divide After PLL (Now 40MHz)
#pragma config FPBDIV = DIV_1 // Pheripheral Bus Clock (At 40KHz)
#pragma config FWDTEN = OFF // Watchdog Timer Disabled
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select
#pragma config JTAGEN = OFF // Disable JTAG
#pragma config FSOSCEN = OFF // Disable Secondary Oscillator
//*****************************UART Functions***********************************
void UART_Config (void) // Baude Rate of 9600, 8-Bit Data , 1 Stop Bit
{
U1MODEbits.BRGH = 0;
U1BRG = 259; //U1BRG = (40M/ (16 * 9.6k))) - 1
U1MODEbits.SIDL = 0; // Continue operation in SLEEP mode
U1MODEbits.IREN = 0; // IrDA is disabled
U1MODEbits.RTSMD = 0; // U1RTS pin is in Flow Control mode
U1MODEbits.UEN = 0b00; // U1TX, U1RX are enabled
U1MODEbits.WAKE = 1; // Wake-up enabled
U1MODEbits.LPBACK = 0; // Loopback mode is disabled
U1MODEbits.RXINV = 0; // U1RX IDLE state is '1'
U1MODEbits.PDSEL = 0b00; // 8-bit data, no parity
U1MODEbits.STSEL = 0; // 1 stop bit
U1STAbits.UTXINV = 0; // U1TX IDLE state is '1'
U1MODEbits.ON = 1; // UART1 is enabled
U1STAbits.URXEN = 1; // UART1 receiver is enabled
U1STAbits.UTXEN = 1; // UART1 transmitter is enabled
}
void Send_UART_Data(unsigned int c) // PIC Sending Data for Pi to Read
{
U1STAbits.UTXEN = 1; // Make sure transmitter is enabled
// while(CTS) // Optional CTS (Clear to Send) use
while(U1STAbits.UTXBF); // Wait while buffer is full
U1TXREG = c; // Transmit character
}
int Read_UART_Data (void) // PIC Reading Sent Data from Pi
{
int c;
while(!U1STAbits.URXDA) // Wait for information to be received
c = (int)U1RXREG; // Convert Character to Value
return c;
}
ADC_To_UART (unsigned int ADC)
{
unsigned int temp_A = 0x00;
unsigned int temp_B = 0x00;
// Splitting a 10 Bit Word Into 2 Bytes [aa aaaa aabb]
// Start Bit = 1 , Stop Bit = 0
// UART Transmission Pattern [1 aaaa aaaa 0 0000 00 bb]
temp_A = ADC >> 2; // MSB(8 Bits) ~ ADC[9:2] [aaaa aaaa]
temp_B = ADC & 0x003; // LSB(2 Bits) ~ ADC[1:0] [0000 00bb]
Send_UART_Data(temp_A);
Send_UART_Data(temp_B);
}
[enter image description here][1]
//*********************Enumerated Variable Declaration**************************
//Program Flow Control
enum Comm_State {Phase1A, Phase1B, Phase1C, Phase1D, Phase1E, Phase2A, Phase2B, Phase2C, Phase2D, Phase2E, Phase2F, Phase2G};
//******************************************************************************
//********************************MAIN******************************************
int main( )
{
//***************************Configuration**********************************
// I/O Definitions
#define UART_TRIS_RX TRISBbits.TRISB13 // UART RX - Reciever Pin (PPS)
#define UART_TRIS_TX TRISBbits.TRISB15 // UART TX - Transmission Pin (PPS)
#define UART_TRIS_CTS_PIC TRISAbits.TRISA4 // UART CTS_1 - Clear to Send - Output [CTS PIC]
#define UART_TRIS_RTS_PIC TRISBbits.TRISB4 // UART RTS_1 - Ready to Send - Output [RTS PIC]
#define UART_TRIS_CTS_PI TRISAbits.TRISA3 // UART CTS_2 - Clear to Send - Input [CTS PI]
#define UART_TRIS_RTS_PI TRISAbits.TRISA2 // UART_RTS_2 - Ready to Send - Input [RTS PI]
#define SPI_TRIS_SCK TRISBbits.TRISB14 // SPI SCK - Serial Clock Pin (PPS?)
#define SPI_TRIS_SDO TRISBbits.TRISB6 // SPI SDO - Serial Data Out Pin (PPS?)
#define SPI_TRIS_CS_1 TRISBbits.TRISB8 // SPI CS1 - DAC 2 Chip Select Pin (PPS?)
#define SPI_TRIS_CS_2 TRISBbits.TRISB7 // SPI CS2 - DAC 1 Chip Select Pin (PPS?)
#define AN4_TRIS TRISBbits.TRISB2 // Analogue Read 3
#define AN3_TRIS TRISBbits.TRISB1 // Analogue Read 2
#define AN2_TRIS TRISBbits.TRISB0 // Analogue Read 1
#define V_REF_TRIS_Plus TRISAbits.TRISA0 // Analogue V_REF(+) (Forms VRange)
#define V_REF_TRIS_Minus TRISAbits.TRISA1 // Analogue V_REF(-) (Forms VRange)
#define Reg_Enable_TRIS_D TRISBbits.TRISB9 // Regulator Digital Control (Output)
#define Reg_Enable_TRIS_M TRISBbits.TRISB12 // Regulator Button (Input)
// Port Input/Output Configuration [TRISB]
TRISB = 0x1004; // All of PortB set as Outputs Except for RB12 (Reg Enable) and RB2 (Input -> Analogue Input (Voltage)) (Port B) = (0000 ... 0100)
TRISA = 0x0003; // Set up A0 [Pin 2] and A1 [Pin 3] as V_REF(+) and V_REF(-) Respectively (Port B) = (0000 ... 0011)
UART_TRIS_RX = 1; // UART Receiver ~ Input
UART_TRIS_TX = 0; // UART Transmission ~ Output
UART_TRIS_CTS_PIC = 0; // UART "CTS_PIC" ~ Output
UART_TRIS_RTS_PIC = 0; // UART "RTS_PIC" ~ Output
UART_TRIS_CTS_PI = 1; // UART "CTS_PI" ~ Input
UART_TRIS_RTS_PI = 1; // UART "RTS_PI" ~ Input
SPI_TRIS_SCK = 0; // SPI Clock ~ Output
SPI_TRIS_SDO = 0; // SPI Data Output ~ Output
SPI_TRIS_CS_1 = 0; // SPI Chip Select 1 ~ Output
SPI_TRIS_CS_2 = 0; // SPI Chip Select 2 ~ Output
AN4_TRIS = 1; // Analogue Read In ~ Input
AN3_TRIS = 1; // Analogue Read In ~ Input
AN2_TRIS = 1; // Analogue Read In ~ Input
V_REF_TRIS_Plus = 1; // V_Ref(+) ~ Input
V_REF_TRIS_Minus = 1; // V_Ref(-) Differential Measurements ~ Input
Reg_Enable_TRIS_D = 0; // Regulator Digital Control (Output)
Reg_Enable_TRIS_M = 1; // Regulator Switch Control (Input)
// Peripheral Pin Select Configurations
U1RXR = 0x0011; // UART PPS Mapping
RPB15R = 0x0001; // UART PPS Mapping
// Analogue Pin Configurations
ANSELB = 0x0028; // RB0 RB1 RB2 = AN2 AN3 AN4 [0001 1100]
ANSELA = 0x0000; // Set all Analogue Inputs of Port A Off
//**************Sub-System Configurations*********************************//
// UART Control Configure
UART_Config(); //UART Control Configure
#define PIC_CTS LATAbits.LATA4 // Output Set Definition [1]
#define PIC_RTS LATBbits.LATB4 // Output Set Definition [2]
#define PI_CTS PORTAbits.RA3 // Input Read Definition [2]
#define PI_RTS PORTAbits.RA2 // Input Read Definition [1]
// Analogue Control Configure
ADC_Config(); // Configure ADC
AD1CON1SET = 0x8000; // Enable ADC
//***************Variable Declarations************************************//
enum Comm_State Communication_State = Phase1A; //Controller Variable
unsigned int temp1 = 0;
unsigned int Comms_Flag_1 = 0;
unsigned int ConFlag = 1;
unsigned int i = 1;
unsigned int UART_ADC_CV_1 = 0;
unsigned int UART_ADC_CV_2 = 0;
unsigned int ADC_CV = 0;
unsigned int UART_ADC_CC_1 = 0;
unsigned int UART_ADC_CC_2 = 0;
unsigned int ADC_CC = 0;
unsigned int DAC_CV = 0;
float I_CC = 0;
float V_CV = 0;
//***************Program Flow - Switch State Controlled*******************//
while(1)
{
switch (Communication_State)
{
case Phase1A: // Check For Pi Ready to Send CV ADC Value
//PIC_CTS = 0;
//Pic_Refresh();
PIC_RTS = 0;
PIC_CTS = 1;
if (PI_RTS == 1)
{
PIC_CTS = 0;
Communication_State = Phase1B;
}
break;
case Phase1B: // Receive CV ~ 12 Bit ADC Value [Two Data Packets with 0.01 Second Delay]
ConFlag = 1;
i = 1;
while (ConFlag == 1)
{
if (PI_RTS == 1 && i == 1)
{
UART_ADC_CV_1 = Read_UART_Data(); //Data Packet 1 Returned - MSB(Bit 15) to Bit 8
i++;
}
else if (PI_RTS == 1 && i == 2)
{
UART_ADC_CV_2 = Read_UART_Data(); //Data Packet 2 Returned - Bit (7)) to LSB(Bit 0)
}
else
{
ConFlag = 0;
}
}
Communication_State = Phase1C;
break;
case Phase1C: // Check for CC Value
delay(); //Ensure that Pi_RTS has gone low after sending last Transmission (Prevents Code from Running Away)
PIC_CTS = 1;
if (PI_RTS == 1)
{
PIC_CTS = 0;
Communication_State = Phase1D;
}
break;
case Phase1D: // Receive CC Value [Two Data Packets with 0.01 Second Delay]
ConFlag = 1;
i = 1;
while (ConFlag == 1)
{
if (PI_RTS == 1 && i == 1)
{
UART_ADC_CC_1 = Read_UART_Data(); //Data Packet 1 Returned - MSB(Bit 15) to Bit 8
i++;
}
else if (PI_RTS == 1 && i == 2)
{
UART_ADC_CC_2 = Read_UART_Data(); //Data Packet 2 Returned - Bit (7)) to LSB(Bit 0)
}
else
{
ConFlag = 0;
}
}
Communication_State = Phase1E;
break;
case Phase1E: // Calculations
// CV Calculations
temp1 = UART_ADC_CV_1 << 8;
ADC_CV = temp1 + UART_ADC_CV_2;
V_CV = ADC_CV * (4.096/4096);
DAC_CV = ADC_CV | 4096;
Comms_Flag_1 = SPI_Transfer(DAC_CV ,1); // Data Transmitted to DAC 1, Upon Transmission LED Turns Green (No Acknowledgement)
// CC Calculations
temp1 = UART_ADC_CC_1 << 8;
ADC_CC = temp1 + UART_ADC_CC_2;
I_CC = ADC_CC * (4.096/4096);
Communication_State = Phase2A;
break;
case Phase2A:
while(1)
{
LATBbits.LATB5 = 1;
}
break;
}
}
return 1;
}
In Read_UART_Data, you have:
while(!U1STAbits.URXDA)
c = (int)U1RXREG;
I think you're missing a semicolon because this is actually:
while (!U1STAbits.URXDA)
c = (int) U1RXREG;
This means that c is set only when the UART receiver is not ready.
What I think you meant is:
while (!U1STAbits.URXDA);
c = (int) U1RXREG;
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.
I m using dspic33f series micro controller to receive SMS from modem SIM800A. I m using interrupt method to receive response from the modem using serial communication . If I send more than one AT command to modem via UART sequentially I'm getting response into the recieve buffer only for 1st command and no response in the receive buffer for the remaining commands though the modem was responding.
After debugging I found the reason for this peculiar behavior. The reason was I was clearing the receive buffer after receiving the response into the buffer and printing on the console i.e. before sending next command to modem via UART using memset function in c.
But on commenting this memset function i was able receive the response into the receive buffer for the all the AT commands that was sent sequentially, if the memset function is not commented then no response is filled in the receive buffer though the modem was responding so please help out in receiving the response into the buffer.
Code which i have written
#include "p33FJ64GS606.h"
#include <stdio.h>
#define FCY 40000000UL
#include <libpic30.h>
#include <string.h>
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF)
_FWDT(FWDTEN_OFF)
_FPOR(FPWRT_PWR128 )
_FICD(ICS_PGD1 & JTAGEN_OFF)
char StringLoop[161];
void Init_Uart1(int uart_no)
{
U1MODEbits.STSEL = 0; // 1-Stop bit
U1MODEbits.PDSEL = 0; // No Parity, 8-Data bits
U1MODEbits.ABAUD = 0; // Auto-Baud disabled
U1MODEbits.BRGH = 0; // Standard-Speed mode
U1BRG = UBRG1_VALUE; // Baud Rate setting for 115200
U1STAbits.UTXISEL0 = 0; // Interrupt after one TX character is transmitted
U1STAbits.UTXISEL1 = 0;
U1STAbits.URXISEL0 = 0;
U1STAbits.URXISEL1 = 0;//jkv
IEC0bits.U1RXIE = 1;
IEC0bits.U1TXIE = 0; // Enable UART TX interrupt
U1MODEbits.UARTEN = 1; // Enable UART
U1STAbits.UTXEN = 1; // Enable UART TX
U1MODEbits.USIDL=0;
}
void UART1_puts(unsigned char data)
{
while (U1STAbits.TRMT==0);
U1TXREG = data;
}
void UART1_send(unsigned char *s)
{
memset(StringLoop,'\0',sizeof(StringLoop)); /* if I comment this line then i can receive the response into the buffer StringLoop continuously else i receive the response only for the 1st AT command and I don't get the response for other AT commands into the StringLoop though the modem is responding*/
while(*s)
{
UART1_puts(*s);
s++;
}
}
void __attribute__((interrupt, no_auto_psv)) _U1RXInterrupt(void)
{
if(IFS0bits.U1RXIF)
{
StringLoop[rcindex++] = U1RXREG;
if (rcindex >= (sizeof(StringLoop) - 1))
rcindex = 0;
}
IFS0bits.U1RXIF=0;
}
}
void main()
{
int i=0,j=0;
Init_Clocks();
Init_Uart2(1);
Init_Uart1(1);
TRISFbits.TRISF1=0;
LATFbits.LATF1=1;
UART1_send("AT+CMGR=1\r\n");
__delay_ms(2000);
printf("stringloop is %s\n",StringLoop);
UART1_send("AT+CPMS=?\r\n");
__delay_ms(2000);
printf("stringloop is %s\n",StringLoop);
UART1_send("AT+CPMS?\r\n");
__delay_ms(2000);
printf("stringloop is %s\n",StringLoop);
}
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