I am trying to control a car/wheeled robot basically with this code. The problem here is that if I send signals faster than 0.9 seconds, the Arduino cannot process it. Is there any way to fix it?
(I have checked the serial monitor from a different computer and it shows the Arduino still receives the signal but it doesn't provide the output to my motor controller).
Any help would be appreciated. Thanks.
#include <Servo.h>
//Using mega 2560 and sabertooth 2x12 dip switch 010111
int onevar;
int twovar;
Servo myservo;
Servo myservo2;
void setup() {
// put your setup code here, to run once:s
pinMode(servo1, OUTPUT);
pinMode(servo2, OUTPUT);
Serial.begin(9600);
myservo.attach(servo1);
myservo2.attach(servo2);
Serial.setTimeout(10);
//works for 10ms 0.9s need to figure out
}
void loop() {
// put your main code here, to run repeatedly:
// Receive up to 7 bytes
if (Serial.available()>0) {
// Wait for characters
onevar = Serial.parseInt();
twovar = Serial.parseInt();
//number = atoi(buffer);
Serial.println(onevar);
Serial.println(twovar);
/* if (Serial.available() > 0) {
number = Serial.read()-'0'; // read the incoming byte:
Serial.print(number);
*/
myservo.write(onevar);
// 93 is stop backward and forward is scalable range 25 to 155
myservo2.write(twovar);
//93 is no steering 30 to 160
}
}
A few things to try:
Serial.begin(9600);
Try setting the baud rate higher (on both ends).
Serial.println(onevar);
Serial.println(twovar);
Comment those out for some testing.
Servo myservo;
Servo myservo2;
2 servos and 1 serial port. It could happen that there is a conflict with the timers (multiple libraries using/setting the same timer). Does it work with 1 servo?
Related
Im struggling with the following scenario: I have 2 ESP32 boards (Dev Kit 1) and each ESP32 has 1 MCP23017 I2C module connected to it. So my goal is to use all 16 pins on MCP 1 as Output and all other 16 pins on second MCP as inputs and be able to "READ" these values (HIGH OR LOW) I Already setup connection using common ground on both ESP and wiring SDA SCL accordingly. I Already tested using input and output on same MCP unit and works fine (displays on COM port a seral.println message) but when I want to do the same thing but connecting from MCP1 output pin 1 to MCP2 input pin 1, nothing happens on the COM port, but when I unplug the jumper wire (which I use to connect input pin to output pin on the protoboard) then it does detect the voltage change and displays the message. Any idea whats going on here? Why I cant bridge from 1 MCP output to another MCP input and be able to detect this on COM port? Im using following code:
#include "Adafruit_MCP23017.h"
Adafruit_MCP23017 mcp1; // Instantiate mcp module object 1, (MCP001)
int dly = 250; // 1/4 second delay
void setup() {
Wire.begin();
Serial.begin(19200);
Serial.println("MCP module 1 Ready");
mcp1.begin(); // "Start" the mcp object
mcp1.pinMode(0, OUTPUT); //set pin "0" on MCP1 as output
mcp1.pinMode(1, INPUT); //set next pin "1" on MCP1 as input
}
void loop() {
mcp1.digitalWrite(0, HIGH); // Set pin HIGH (on)
if (mcp1.digitalRead (1 == HIGH)) {
Serial.println("Continuity Detected at Pin 1 ");
}
mcp1.digitalWrite(0, LOW); // Set pin LOW (off)
delay(dly); // On for 1/4 second
}
I solved the problem by just removing or commenting out the line 27 (mcp1.digitalWrite(0, LOW);) Now works the way I want. Thanks #romkey for your time and help.
I am trying to connect my TM4C123GH6PM Microcontroller from Texas Instruments with my Smartphone and use it to control an alarm clock and LED Lights. (the LEDs are controlled over a Transistor, which is controlled over an GPIO Pin).
I have some experience with coding in C++ and the TM4C123GH6PM, but I am still learning a lot. So please excuse some foolish mistakes I might have made.
I want to connect the ESP8266 with the Microcontroller using UART and the TivaWare Framework.
I have written some code and my UART works correctly (I tested it by sending chars from UART 4 to 3).
According to the AT commands of ESP8266 It should respond to "AT" with "OK". But whenever I send something to the ESP it responds with exactly what I sent to it. I checked the wiring, and that's not The Issue. Or at least I think so. Please correct me, if the wiring is wrong.
ESP -> TM4C123GH6PM:
GND -> GND
VCC -> 3.3V
Tx -> Rx (UART3 / PC6)
Rx -> Tx (UART4 / PC5)
CH_PD -> 3.3V
I also checked for the power consumption of the ESP. Everything is powered by the USB-port of my laptop, since that helps keep the cable mess down. I monitor the power consumption with (https://www.amazon.de/gp/product/B07C8CM5TG/ref=ppx_yo_dt_b_asin_title_o08_s00?ie=UTF8&psc=1). The ESP is drawing about 150mA from the computer, but the port can provide a lot more. I checked with some LEDs and 400mA is not a problem.
Can anyone help me? I am working on this now for over two days and can't find a Solution. What is the Problem with the ESP not responding correctly to the AT command? The blue light is one, when the code is running.
PS: The attached code contains also code for the alarm clock control and LEDs. I attached it, since it could be part of the problem, but some of it is commented out and most of it is not used.
#include<stdint.h>
#include<stdbool.h>
#include"inc/hw_ints.h"
#include"inc/hw_memmap.h"
#include"inc/hw_types.h"
#include"driverlib/gpio.h"
#include"driverlib/sysctl.h"
#include"driverlib/timer.h"
#include"driverlib/interrupt.h"
#include"driverlib/uart.h"
#include"driverlib/pin_map.h"
#include "driverlib/rom.h"
// stores the time since system start in ms
uint32_t systemTime_ms;
//bools or controling the alarm clock and LEDS
bool an_aus = false;
bool alarm_clock = false;
void InterruptHandlerTimer0A (void)
{
// Clear the timer interrupt flag to avoid calling it up again directly
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
// increase the ms counter by 1 ms
systemTime_ms++;
}
void clockSetup(void)
{
uint32_t timerPeriod;
//configure clock
SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ| SYSCTL_OSC_MAIN);
//activate peripherals for the timer
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
// configure timers as 32 bit timers in periodic mode
TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
// set the variable timerPeriod to the number of periods to generate a timeout every ms
timerPeriod = (SysCtlClockGet()/1000);
// pass the variable timerPeriod to the TIMER-0-A
TimerLoadSet(TIMER0_BASE, TIMER_A, timerPeriod-1);
// register the InterruptHandlerTimer0A function as an interrupt service routine
TimerIntRegister(TIMER0_BASE, TIMER_A, &(InterruptHandlerTimer0A));
// activate the interrupt on TIMER-0-A
IntEnable(INT_TIMER0A);
// generate an interrupt when TIMER-0-A generates a timeout
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
// all interrupts are activated
IntMasterEnable();
// start the timer
TimerEnable(TIMER0_BASE, TIMER_A);
}
void UART (void)
{
//configure UART 4:
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART4));
//GPIO pins for transmitting and receiving
GPIOPinConfigure(GPIO_PC4_U4RX);
GPIOPinConfigure(GPIO_PC5_U4TX);
GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);
//configure UART 8Bit, no parity, baudrat 38400
UARTConfigSetExpClk(UART4_BASE, SysCtlClockGet(), 38400, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
//configure UART 3:
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART3));
GPIOPinConfigure(GPIO_PC6_U3RX);
GPIOPinConfigure(GPIO_PC7_U3TX);
GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);
UARTConfigSetExpClk(UART3_BASE, SysCtlClockGet(), 38400, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
}
void delay_ms(uint32_t waitTime)
{
// Saves the current system time in ms
uint32_t aktuell = systemTime_ms;
// Wait until the current system time corresponds to the sum of the time at the start of the delay and the waiting time
while(aktuell + waitTime > systemTime_ms);
}
void ex_int_handler(void)
{
// press the button to start timer for alarm clock
alarm_clock = true;
GPIOIntClear(GPIO_PORTF_BASE,GPIO_PIN_4);
}
int main(void)
{
//Peripherals for LED and GPIO
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
//UART
UART();
//Timer
clockSetup();
// button
GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,GPIO_PIN_4);
GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);
//OnboardLED
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_1);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_3);
//Interrupt Timer
GPIOIntDisable(GPIO_PORTF_BASE,GPIO_PIN_4);
GPIOIntClear(GPIO_PORTF_BASE,GPIO_PIN_4);
GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_FALLING_EDGE);
GPIOIntRegister(GPIO_PORTF_BASE,ex_int_handler);
GPIOIntEnable(GPIO_PORTF_BASE,GPIO_PIN_4);
//Transistor Gate
GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,GPIO_PIN_0);
//GPIOPadConfigSet(GPIO_PORTB_BASE,GPIO_PIN_0,GPIO_STRENGTH_6MA,GPIO_PIN_TYPE_STD_WPU);
//debugging only: save all the received data from the ESP in an array to look at while debugging
int32_t data[20] = {0};
int32_t j = 0;
//Code for debugging the UART and ESP8266
while(1){
//Checks for Data in the FIFO
while(!UARTCharsAvail(UART4_BASE));
//send AT-command to ESP8266
UARTCharPut(UART4_BASE, 'A');
while(UARTBusy(UART4_BASE));
UARTCharPut(UART4_BASE, 'T');
while(UARTBusy(UART4_BASE));
if(UARTCharsAvail(UART3_BASE))
{
while(UARTCharsAvail(UART3_BASE))
{
//Read data from the FIFO in UART3 -> received from ESP8266
data[j] = UARTCharGet(UART3_BASE);
j++;
}
}
//clear array when its full
if (j >= 20)
{
j = 0;
for(int32_t a = 0; a <21; a++)
{
data[a] = 0;
}
}
}
//code to run the alarm clock and leds
/*
while(1)
{
if (alarm_clock)
{
GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3,GPIO_PIN_3);
//Wait
delay_ms(30600000);
GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_0,GPIO_PIN_0);
alarm_clock = false;
GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3,0x00);
//Start Red LED blinking when it is finished
while(1)
{
GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,GPIO_PIN_1);
delay_ms(1000);
GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,0x00);
delay_ms(1000);
}
}
}
*/
}
According to the AT commands of ESP8266 It should respond to "AT" with
"OK". But whenever I send something to the ESP it responds with
exactly what I sent to it
Modems with AT Commands commonly ship with the echo mode turned on, so that when you are interacting with it manually through serial port, it will echo the characters you sent first, and then send the reply.
So, when you are automating the process, you first send the characters, then wait for the reply until you reach a '\r'. Well, you are reaching a '\r', but its the one from the echo. You might have some other characters next. You send AT, you should receive AT first, then you have the OK.
To solve this problem, you should turn echo mode off.
The command to turn off echo is ATE0.
today I tried to setup a servo motor running along with this sketch on Arduino. For some reason, when I add the setup lines for the servo, the software serial port doesn't receive data normally. I tried to change the software serial to the normal Serial port on Arduino but the same thing happens.
#include<SoftwareSerial.h>
#include<Servo.h>
Servo myServo;
SoftwareSerial BT1(3,2); // TX, RX
int val;
int servoPin = 7;
int ledPin = 10;
void setup() {
pinMode(ledPin,OUTPUT);
BT1.begin(9600);
myServo.attach(servoPin);
myServo.writeMicroseconds(2000); //2 ms for Tower Pro SG 90 Servo
myServo.write(90); //Initialize at servo's middle point
}
void loop() {
if (BT1.available()) {
int i = (int)BT1.read();
setIntensity(i);
}
}
void setIntensity(int value) {
if (value >= 0 && value <= 110) {
analogWrite(ledPin, value);
}
}
When I comment out the setup lines for myServo, the Arduino works like a charm. How can I solve this? I'm using an Arduino Duemilanove.
NeoSWSerial is a suitable replacement for SoftwareSerial. NeoSWSerial won't interfere with Servo, because it doesn't use any extra resources, and it doesn't block interrupts for long periods of time.
It's also available from the IDE Library Manager, under the menu Sketch -> Include Library -> ManageLibraries.
So, I am an amateur programmer at Arduino, and have never used Arduino MKR1000 before. I used an Arduino Uno and wrote the attached code that detects heart beat and temperature using the Grove Ear clip heart beat sensor and the Grove Temperature sensor and then prints them in the console every 20 seconds. Previously, this code was written to show in an Grove OLED screen but later simplified it back to using it by reading on just the console.
Because of the wearable nature of my project I have to switch to using a MKR1000 instead. I know the MKR1000 uses the same Arduino code and should work the same way as it did on my Arduino Uno, but I have been having some issues with using the MKR1000 with the same code.
The issue is that the code only runs once and stops after that. While I am aware of the for loops and how it works to certain extent, I cannot find the exact issue why it stops looping instead of taking the data constantly and publishing it on the console, like it did previously with my Uno.
Just for the heads up, following is how my code reacted to Arduino Uno:
The result in the console shows:
Please be ready
This will now begin
then it prints number 1 to 20 every second followed by sensor readings. After publishing this, it repeats this process again.
Again sorry for the inconvenience and thank you for your help.
I used direct codes from the documentation blog of the sensors (bottom of the page of the linked page):
Grove heart bear sensor
Grove Temperature sensor
#define LED 4//indicator, Grove - LED is connected with D4 of Arduino
boolean led_state = LOW;//state of LED, each time an external interrupt
//will change the state of LED
float tempa;
int tempPin = 0;
unsigned char counter;
unsigned long temp[21];
unsigned long sub;
bool data_effect=true;
unsigned int heart_rate;//the measurement result of heart rate
const int max_heartpluse_duty = 2000;//you can change it follow your system's request.
//2000 meams 2 seconds. System return error
//if the duty overtrip 2 second.
void setup()
{
pinMode(LED, OUTPUT);
Serial.begin(9600);
while (!Serial){
;
}
Serial.println("Please be ready");
delay(5000);
arrayInit();
Serial.println("This will now begin.");
attachInterrupt(0, interrupt, RISING);//set interrupt 0,digital port 2
}
void loop()
{
digitalWrite(LED, led_state);//Update the state of the indicator
}
/*Function: calculate the heart rate*/
void sum()
{
if(data_effect)
{
heart_rate=1200000/(temp[20]-temp[0]);//60*20*1000/20_total_time
Serial.print("Heart_rate_is:\t");
Serial.println(heart_rate);
tempa = analogRead(tempPin);
tempa = tempa * 0.11;
Serial.print("Body Temperature = ");
Serial.print(tempa);
Serial.print("*C");
Serial.println();
delay(1000);
}
data_effect=1;//sign bit
}
/*Function: Interrupt service routine.Get the sigal from the external interrupt*/
void interrupt()
{
temp[counter]=millis();
Serial.println(counter,DEC);
switch(counter)
{
case 0:
sub=temp[counter]-temp[20];
break;
default:
sub=temp[counter]-temp[counter-1];
break;
}
if(sub>max_heartpluse_duty)//set 2 seconds as max heart pluse duty
{
data_effect=0;//sign bit
counter=0;
Serial.println("measurement error,test will restart!" );
arrayInit();
}
else if (counter==20&&data_effect)
{
counter=0;
sum();
}
else if(counter!=20&&data_effect)
{
counter++;
}
else
{
counter=0;
data_effect=1;
}
}
/*Function: Initialization for the array(temp)*/
void arrayInit()
{
for(unsigned char i=0;i < 20;i ++)
{
temp[i]=0;
}
temp[20]=millis();
}
Your problem is the interrupt pin. On the Arduino UNO the digital pin D2 is interrupt pin 0, as you have done in your code. On the Arduino MKR1000 the interrupt pin is tha same as the physical pin number, so if you'r connecting to pin 2, change attachInterrupt(0, interrupt, RISING); to attachInterrupt(2, interrupt, RISING);
If you wanna be sure to use the right pin you can use digitalPinToInterrupt(pin) to get the correct interrupt number on any Arduino board. Like this attachInterrupt(digitalPinToInterrupt(pin), interrupt, RISING); where pin is the physical pin number.
Info
On the Arduino MKR1000 you can use pin 0, 1, 4, 5, 6, 7, 8, 9, A1 and A2 as interrupt
For a project I am working on I need to connect a rotary encoder to my Arduino Mega(2560) board. The rotary encoder will act as a sort of very precise scrolling wheel to position an object in my python code. I found this Arduino code which does very nicely what I want. However, in order to implenemt the encoder readout in python I somehow need to "connect" my Input I recieve from the Arduino board to my Python Code. I tried to somehow "convert" the Arduino code into Python code and came across the idependencies of pySerial and pyfirmata which looked promising. yet, there are certain functions in the Arduino that are not mimicked by Python, such as the attachInterrupt() function or volatile unsigned int.
I was hoping someone could point me in the right direction of to convert the following Arduino code for the rotary encoder into Python code.
// Encoder connect to digitalpin 2 and 3 on the Arduino.
volatile unsigned int counter = 0; //This variable will increase or decrease depending on the rotation of encoder
void setup() {
Serial.begin (9600);
//Setting up interrupt
//A rising pulse from encodenren activated ai0(). AttachInterrupt 0 is DigitalPin nr 2 on moust Arduino.
attachInterrupt(0, ai0, RISING);
//B rising pulse from encodenren activated ai1(). AttachInterrupt 1 is DigitalPin nr 3 on moust Arduino.
attachInterrupt(1, ai1, RISING);
}
void loop() {
// Send the value of counter
Serial.println (counter);
}
void ai0() {
// ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
// Check pin 3 to determine the direction
if(digitalRead(3)==LOW) {
counter++;
}else{
counter--;
}
}
void ai1() {
// ai0 is activated if DigitalPin nr 3 is going from LOW to HIGH
// Check with pin 2 to determine the direction
if(digitalRead(2)==LOW) {
counter--;
}else{
counter++;
}
}
created 2014
by Ben-Tommy Eriksen
https://github.com/BenTommyE/BenRotaryEncoder
Thank you