How can I change LED's brightness with PWM and USART in USART1_IRQHandler? - stm32

I am using STM32F4 discovery board and I am working on changing LED brightness and timer period using ADC and USART.
I use DMA to fetch ADC values, selected TIM4 for PWM and selected USART1 for USART. ADC, USART and PWM are working well so far, but USART1_IRQHandler() is not working as expected.
How can I adjust timer period and LED brightness with PWM and ADC in the following implementation of USART1_IRQHandler()?
void USART1_IRQHandler()
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) )
{
delay(168000);
i = USART_ReceiveData(USART1);
if(i == '1'){
TIMOC_InitStruct.TIM_Pulse=pwm_value;
TIM_OC1Init(TIM4,&TIMOC_InitStruct);
TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);
UARTSend("3 led aktif\r\n",sizeof("LED 4 ON\r\n"));
}
else if(i == '2')
{
TIMOC_InitStruct.TIM_Pulse=pwm_value;
TIM_OC1Init(TIM4,&TIMOC_InitStruct);
TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);
TIMOC_InitStruct.TIM_Pulse=pwm_value;
TIM_OC2Init(TIM4,&TIMOC_InitStruct);
TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable);
UARTSend("2 led aktif\r\n",sizeof("LED 4 ON\r\n"));
}
else if(i == '4')
{
TIMOC_InitStruct.TIM_Pulse=pwm_value;
TIM_OC1Init(TIM4,&TIMOC_InitStruct);
TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);
TIMOC_InitStruct.TIM_Pulse=pwm_value;
TIM_OC2Init(TIM4,&TIMOC_InitStruct);
TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable);
TIMOC_InitStruct.TIM_Pulse=pwm_value;
TIM_OC3Init(TIM4,&TIMOC_InitStruct);
TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable);
UARTSend("4 led aktif\r\n",sizeof("LED 4 ON\r\n"));
}
else if(i == '4')
{
TIMOC_InitStruct.TIM_Pulse=pwm_value;
TIM_OC1Init(TIM4,&TIMOC_InitStruct);
TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);
TIMOC_InitStruct.TIM_Pulse=pwm_value;
TIM_OC2Init(TIM4,&TIMOC_InitStruct);
TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable);
TIMOC_InitStruct.TIM_Pulse=pwm_value;
TIM_OC3Init(TIM4,&TIMOC_InitStruct);
TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable);
TIMOC_InitStruct.TIM_Pulse=pwm_value;
TIM_OC4Init(TIM4,&TIMOC_InitStruct);
TIM_OC4PreloadConfig(TIM4,TIM_OCPreload_Enable);
UARTSend("4 led aktif\r\n",sizeof("LED 4 ON\r\n"));
}
else
{
Hello();
UARTSend("Please enter another number:\n",sizeof("Please enter another number:\n"));
}
} USART_ClearITPendingBit(USART1,USART_IT_RXNE);
}

About your USART1_IRQHandler, have you check if the interrupt is active with
__HAL_RCC_UART4_CLK_ENABLE();
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
and if you enable it with this call
UART_Receive_IT( &huart1 );
I am using STM32Cube, repository V1.25.0.
Now, about your code inside the USART1_IRQHandler(), you could use shortcut to handle what you want to do. If I understand, you have 4 leds to control with the Timer4 and 4 channels.
The pulse is the Output Compare value (TIM4->CCR1 for channel 1). So, I would start the timer with a pulse equal to the Period (or zero. See note below).
From that point, if you want to change the brightness, you have just to change the pulse width with
__HAL_TIM_SET_COMPARE( htim4, TIM_CHANNEL_1, pwm_value);
or with
TIM4->CCR1 = pwm_value;
You could also disable any channel with
__HAL_TIM_DISABLE_IT( htim4, TIM_CHANNEL_1);
__HAL_TIM_ENABLE_IT( htim4, TIM_CHANNEL_1);
So, you get something like that
if(i == '1'){
TIM4->CCR1 = pwm_value;
} else if(i == '2') {
TIM4->CCR1 = pwm_value;
TIM4->CCR2 = pwm_value;
} ...
Note: I don't know how are connected your leds. If the led is connected to Vcc and the other end to the MPU pin, a LOW pulse will turn ON the led and HIGH pulse will turn it OFF.

Related

STM32 BluePill LED flasher acts strange using HAL_GPIO_TogglePin

I have two simple LED flasher programs the flash at 1 sec intervals for my BluePills.One method uses HAL_GPIO_TogglePin to toggle the LED state and the other uses Set and Reset to toggle the LED state. The Set and Reset functions as expected but the HAL_GPIO_TogglePin definitely is working but it has a almost PWM effect part of the time. I have tried both methods on 2 different Bluepills with same results for both.
while (1)
{
if (__HAL_TIM_GET_COUNTER(&htim1) >= 32000)
{
HAL_GPIO_TogglePin(User_LED_GPIO_Port, User_LED_Pin);
}
and
while (1)
{
if (__HAL_TIM_GET_COUNTER(&htim1) >= 32000)
{
HAL_GPIO_WritePin(User_LED_GPIO_Port, User_LED_Pin, GPIO_PIN_SET);
}
else {
HAL_GPIO_WritePin(User_LED_GPIO_Port, User_LED_Pin, GPIO_PIN_RESET);
}
Thanks Codo, you were 100% right. I modified it to
if ((__HAL_TIM_GET_COUNTER(&htim1) == 32000) || (__HAL_TIM_GET_COUNTER(&htim1)==0))
{
HAL_GPIO_TogglePin(User_LED_GPIO_Port, User_LED_Pin);
timer_val = __HAL_TIM_GET_COUNTER(&htim1);
}
Funny thing is I originally followed the Digikey example and it did the same thing.
while (1)
{
// If enough time has passed (1 second), toggle LED and get new timestamp
if (__HAL_TIM_GET_COUNTER(&htim16) - timer_val >= 10000)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
timer_val = __HAL_TIM_GET_COUNTER(&htim16);
}
oh well, for what i want, the Set Reset works better anyways. Thanks

I have two i2c devices. Both alone work well, but when I read from one, and then write to the other, the second one is not an ancknowledging

I have two devices MPU6050 and EEPROM 24C256. I can write and read from both alone. But when I try to read from MPU6050 and than write data to EEPROM in the same session, the EEPROM does not respond. I am using mbed OS libraries. And my question is.. Is it library, code or hardware problem?
MPU6050 read sequence:
enter image description here
EEPROM write page sequance:
enter image description here
//CODE
const char imuAddress = 0x68<<1;
const char imuDataAddress = 0x3B;
const char eepAddress = 0xA0;
const char data[3] = {1.1, 2.2, 3.3};
char acc[3];
//reading acceleration data from IMU
while(true){
i2c.start();
if(i2c.write(imuAddress) != 1){
i2c.stop();
continue;
}
if(i2c.write(imuDataAddress) != 1){
i2c.stop();
continue;
}
i2c.start();
if(i2c.write(imuAddress | 0x01) != 1){
i2c.stop();
continue;
}
for (int i = 0; i < 2; i++){
i2c.read(1); //read and respond ACK to continue
}
i2c.read(0); //read and respond NACK to stop reading
i2c.stop();
break;
}
//write data to EEPROM
while(true){
i2c.start();
if(i2c.write(eepAddress) != 1){ //here is the problem (EEPROM does not respond)
i2c.stop();
continue;
}
if(i2c.write(0x00) != 1){
i2c.stop();
continue;
}
if(i2c.write(0x00) != 1){
i2c.stop();
continue;
}
bool ack = true;
for(int i = 0; i < 3; i++){
if(i2c.write(data[i]) != 1){
i2c.stop();
ack = false;
break;
}
}
if (ack == true){
i2c.stop();
break;
}
}
I have a couple initial thoughts, but do you have access to an oscilloscope? It is odd that each one works individually. This makes me think that it may be an issue between the transition. (Possibly try a delay between each one? Also, possibly remove the stops in the initial read as they aren't necessary)
I think the best way to figure this out is to post a scope trace of the messaging for each one running individually and a trace of them running back to back.

STM32F4 Discovery

I have STM32F4 Discovery. I use IAR embedded Workbench. I am new to this kit. I want to measure distance. my code does not give an error. the distance is always zero. What could be the error? please help me . thanks everyone
#include "stm32f4_discovery.h"
#include "delay.h"
uint32_t Read_Distance(void);
void Init();
uint32_t distance ;
int main()
{
Init(); // initialisation de pin
SysTick_Init(); // pour pouvoire utiliser la fonction delay :)
while (1)
{
distance=Read_Distance();
delay_nms(100);
}
}
void Init()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitTypeDef gpioStructure;
gpioStructure.GPIO_Pin = GPIO_Pin_10;
gpioStructure.GPIO_Mode = GPIO_Mode_OUT;
gpioStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOD, &gpioStructure);
gpioStructure.GPIO_Pin = GPIO_Pin_11;
gpioStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init(GPIOD, &gpioStructure);
}
//Les Pins pour le Test sont PD10 (Trig) et PD11(echo)
uint32_t Read_Distance(void)
{
__IO uint8_t flag=0;
__IO uint32_t disTime=0;
GPIO_SetBits(GPIOD,GPIO_Pin_10);
delay_nus(10);
GPIO_ResetBits(GPIOD,GPIO_Pin_10);
while(flag == 0)
{
while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_11) == SET)
{
disTime++;
flag = 1;
}
}
return disTime;
}
Looks like you're using one of those ultrasonic distance measurement modules
Try this:
while(flag == 0)
{
disTime++;
if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_11) == SET)
{
flag = 1;
}
}
You should use one of the hardware timers to get a more accurate time measurement.
Now I've had time to think more about it I remember now that you get a pulse sent back with a width proportional to the distance. I think this is the correct answer:
// Wait for pulse to start
while (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_11) == RESET)
{
NOP;
}
// Measure pulse width
while(flag == 0)
{
disTime++;
// Has pulse ended
if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_11) == RESET)
{
flag = 1;
}
}
You may also want to tackle the case where the pulse is never received because this could will block forever.
If I understand correctly, D10 is wired to D11 and you want to check how long your signal remains high. If this is the case, you should increment a counter in timer interrupt handler when your pin is high and reset that counter variable once you've read it.

Why Arduino needs to be restarted after PS2 controller communication in Arduino? And how to to do this via coding?

When I ran the code for a drivetrain and opened serial monitor it was working, but when I powered on Arduino via dc Jack and ran the code. It was not working, because code is needed to restart after connection. I want to know that how can I solve this problem of PS2 communication and run my drivetrain without restart or starting serial monitor.
Code that I uploaded was given in this instructable
http://www.instructables.com/id/Control-anything-with-ps2-controller-and-Arduino-/
I got my answer by experimenting a lot. First thing is that you have to either restart your arduino or configure your pin after connection of ps2 to arduino. This can be done by 2 ways :
1) Restart arduino after connection by code or
2) configure again after connection
1 option you know well, i am discussing 2nd i.e configure :
as you know that you have already configured pins by function ps2x.config_gamepad();
Now you have to reconfigure it after connection of ps2 to arduino, you can use a function called reconfig_gamepad(); after read_gamepad(); in void loop.
my code for holonomic drive train is below find out comments // there are total four commented lines in code. good luck. Hope this will solve your problem also.
#include <PS2X_lib.h> //for v1.6
int dir1=13;
int dir2=11;
int dir3=9;
int dir4=7;
int pwm1=12;
int pwm2=10;
int pwm3=8;
int pwm4=6;
int value_mapped;
/******************************************************************
* set pins connected to PS2 controller:
* - 1e column: original
* - 2e colmun: Stef?
* replace pin numbers by the ones you use
******************************************************************/
#define PS2_DAT 44 //14
#define PS2_CMD 46 //15
#define PS2_SEL 48 //16
#define PS2_CLK 50 //17
/******************************************************************
* select modes of PS2 controller:
* - pressures = analog reading of push-butttons
* - rumble = motor rumbling
* uncomment 1 of the lines for each mode selection
******************************************************************/
//#define pressures true
#define pressures false
//#define rumble true
#define rumble false
PS2X ps2x; // create PS2 Controller Class
//right now, the library does NOT support hot pluggable controllers, meaning
//you must always either restart your Arduino after you connect the controller,
//or call config_gamepad(pins) again after connecting the controller.
int error = 0;
byte type = 0;
byte vibrate = 0;
void setup(){
Serial.begin(57600);
pinMode(dir1,OUTPUT);
pinMode(dir2,OUTPUT);
pinMode(dir3,OUTPUT);
pinMode(dir4,OUTPUT);
pinMode(pwm1,OUTPUT);
pinMode(pwm2,OUTPUT);
pinMode(pwm3,OUTPUT);
pinMode(pwm4,OUTPUT);
delay(1000); //added delay to give wireless ps2 module some time to startup, before configuring it
//CHANGES for v1.6 HERE!!! **************PAY ATTENTION*************
if_error_is_found: // <!---- changed here --->
//setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble);
if(error == 0){
Serial.print("Found Controller, configured successful ");
Serial.print("pressures = ");
if (pressures)
Serial.println("true ");
else
Serial.println("false");
Serial.print("rumble = ");
if (rumble)
Serial.println("true)");
else
Serial.println("false");
Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;");
Serial.println("holding L1 or R1 will print out the analog stick values.");
Serial.println("Note: Go to www.billporter.info for updates and to report bugs.");
}
else if(error == 1)
{
Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips");
goto if_error_is_found; // <!---- changed here --->
}
else if(error == 2)
Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");
else if(error == 3)
Serial.println("Controller refusing to enter Pressures mode, may not support it. ");
// Serial.print(ps2x.Analog(1), HEX);
type = ps2x.readType();
switch(type) {
case 0:
Serial.print("Unknown Controller type found ");
break;
case 1:
Serial.print("DualShock Controller found ");
break;
case 2:
Serial.print("GuitarHero Controller found ");
break;
case 3:
Serial.print("Wireless Sony DualShock Controller found ");
break;
}
}
void loop() {
/* You must Read Gamepad to get new values and set vibration values
ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255)
if you don't enable the rumble, use ps2x.read_gamepad(); with no values
You should call this at least once a second
*/
if(error == 1) //skip loop if no controller found
return;
if(type == 2){ //Guitar Hero Controller
ps2x.read_gamepad(); //read controller
if(ps2x.ButtonPressed(GREEN_FRET))
Serial.println("Green Fret Pressed");
if(ps2x.ButtonPressed(RED_FRET))
Serial.println("Red Fret Pressed");
if(ps2x.ButtonPressed(YELLOW_FRET))
Serial.println("Yellow Fret Pressed");
if(ps2x.ButtonPressed(BLUE_FRET))
Serial.println("Blue Fret Pressed");
if(ps2x.ButtonPressed(ORANGE_FRET))
Serial.println("Orange Fret Pressed");
if(ps2x.ButtonPressed(STAR_POWER))
Serial.println("Star Power Command");
if(ps2x.Button(UP_STRUM)) //will be TRUE as long as button is pressed
Serial.println("Up Strum");
if(ps2x.Button(DOWN_STRUM))
Serial.println("DOWN Strum");
if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed
Serial.println("Start is being held");
if(ps2x.Button(PSB_SELECT))
Serial.println("Select is being held");
if(ps2x.Button(ORANGE_FRET)) { // print stick value IF TRUE
Serial.print("Wammy Bar Position:");
Serial.println(ps2x.Analog(WHAMMY_BAR), DEC);
}
}
else { //DualShock Controller
ps2x.read_gamepad(); //read controller and set large motor to spin at 'vibrate' speed
ps2x.reconfig_gamepad(); // <!---- changed here --->
if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed
Serial.println("Start is being held");
if(ps2x.Button(PSB_SELECT))
Serial.println("Select is being held");
if(ps2x.Button(PSB_PAD_UP)) { //will be TRUE as long as button is pressed
Serial.print("Up held this hard: ");
Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC);
}
if(ps2x.Button(PSB_PAD_RIGHT)){
Serial.print("Right held this hard: ");
Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC);
}
if(ps2x.Button(PSB_PAD_LEFT)){
Serial.print("LEFT held this hard: ");
Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC);
}
if(ps2x.Button(PSB_PAD_DOWN)){
Serial.print("DOWN held this hard: ");
Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC);
}
vibrate = ps2x.Analog(PSAB_CROSS); //this will set the large motor vibrate speed based on how hard you press the blue (X) button
if (ps2x.NewButtonState()) { //will be TRUE if any button changes state (on to off, or off to on)
if(ps2x.Button(PSB_L3))
Serial.println("L3 pressed");
if(ps2x.Button(PSB_R3))
Serial.println("R3 pressed");
if(ps2x.Button(PSB_L2))
Serial.println("L2 pressed");
if(ps2x.Button(PSB_R2))
Serial.println("R2 pressed");
if(ps2x.Button(PSB_TRIANGLE))
Serial.println("Triangle pressed");
}
if(ps2x.ButtonPressed(PSB_CIRCLE)) //will be TRUE if button was JUST pressed
Serial.println("Circle just pressed");
if(ps2x.NewButtonState(PSB_CROSS)) //will be TRUE if button was JUST pressed OR released
Serial.println("X just changed");
if(ps2x.ButtonReleased(PSB_SQUARE)) //will be TRUE if button was JUST released
Serial.println("Square just released");
// if(ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) { //print stick values if either is TRUE
Serial.println("Stick Values:");
Serial.print(ps2x.Analog(PSS_LY), DEC); //Left stick, Y axis. Other options: LX, RY, RX
//Forward Direction And BAckward Diretion
if(ps2x.Button(PSB_R1)){
if(ps2x.Analog(PSS_RY)>=0)
{
//Forward Direction
if(ps2x.Analog(PSS_RY)<127)
{
Serial.println("All MOtor Running Forward");
digitalWrite(dir1,LOW);
digitalWrite(dir2,HIGH);
digitalWrite(dir3,HIGH);
digitalWrite(dir4,LOW);
value_mapped=map(ps2x.Analog(PSS_RY),127,0,0,80);
analogWrite(pwm1,value_mapped);
analogWrite(pwm2,value_mapped);
analogWrite(pwm3,value_mapped);
analogWrite(pwm4,value_mapped);
}
//BAckward Direction
if(ps2x.Analog(PSS_RY)>=127)
{
Serial.println("All MOtor Running Backward");
digitalWrite(dir1,HIGH);
digitalWrite(dir2,LOW);
digitalWrite(dir3,LOW);
digitalWrite(dir4,HIGH);
value_mapped=map(ps2x.Analog(PSS_RY),127,255,0,80);
analogWrite(pwm1,value_mapped);
analogWrite(pwm2,value_mapped);
analogWrite(pwm3,value_mapped);
analogWrite(pwm4,value_mapped);
}
}
// LEft OR Right Direction
if(ps2x.Analog(PSS_RX)>=0)
{
//Left diretion
if(ps2x.Analog(PSS_RX)<128)
{
Serial.println("All MOtor Running Left");
digitalWrite(dir1,HIGH);
digitalWrite(dir2,HIGH);
digitalWrite(dir3,LOW);
digitalWrite(dir4,LOW);
value_mapped=map(ps2x.Analog(PSS_RX),128,0,0,80);
analogWrite(pwm1,value_mapped);
analogWrite(pwm2,value_mapped);
analogWrite(pwm3,value_mapped);
analogWrite(pwm4,value_mapped);
}
//Right Direction
if(ps2x.Analog(PSS_RX)>128)
{
Serial.println("All MOtor Running Right");
digitalWrite(dir1,LOW);
digitalWrite(dir2,LOW);
digitalWrite(dir3,HIGH);
digitalWrite(dir4,HIGH);
value_mapped=map(ps2x.Analog(PSS_RX),128,255,0,80);
analogWrite(pwm1,value_mapped);
analogWrite(pwm2,value_mapped);
analogWrite(pwm3,value_mapped);
analogWrite(pwm4,value_mapped);
}
}
//All MOtors Clock
if( (ps2x.Analog(PSS_LX)<128) )
{
Serial.println("CLOCKWISE RUNNING ALL MOTORS");
digitalWrite(dir1,LOW);
digitalWrite(dir2,LOW);
digitalWrite(dir3,LOW);
digitalWrite(dir4,LOW);
value_mapped=map(ps2x.Analog(PSS_LX),128,0,0,80);
analogWrite(pwm1,value_mapped);
analogWrite(pwm2,value_mapped);
analogWrite(pwm3,value_mapped);
analogWrite(pwm4,value_mapped);
}
//All MOtors Anti-CLockwise
if(ps2x.Analog(PSS_LX)>128)
{
Serial.println("CLOCKWISE RUNNING ALL MOTORS");
digitalWrite(dir1,HIGH);
digitalWrite(dir2,HIGH);
digitalWrite(dir3,HIGH);
digitalWrite(dir4,HIGH);
value_mapped=map(ps2x.Analog(PSS_LX),128,255,0,80);
analogWrite(pwm1,value_mapped);
analogWrite(pwm2,value_mapped);
analogWrite(pwm3,value_mapped);
analogWrite(pwm4,value_mapped);
}
}
if(ps2x.Button(PSB_L1)){
if((ps2x.Analog(PSS_LX)>=120) && (ps2x.Analog(PSS_LX)<=128)){
analogWrite(pwm1,0);
analogWrite(pwm3,0);
}
//dIAGONAL L
if(ps2x.Analog(PSS_LX)<120)
{
Serial.println("CLOCKWISE RUNNING ALL MOTORS");
digitalWrite(dir1,LOW);
digitalWrite(dir3,HIGH);
value_mapped=map(ps2x.Analog(PSS_LX),128,0,0,80);
analogWrite(pwm1,value_mapped);
analogWrite(pwm3,value_mapped);
}
//dIAGONAL R
if(ps2x.Analog(PSS_LX)>=128)
{
Serial.println("CLOCKWISE RUNNING ALL MOTORS");
digitalWrite(dir2,HIGH);
digitalWrite(dir4,LOW);
value_mapped=map(ps2x.Analog(PSS_LX),128,255,0,80);
analogWrite(pwm2,value_mapped);
analogWrite(pwm4,value_mapped);
}
}
Serial.print(",");
Serial.print(ps2x.Analog(PSS_LX), DEC);
Serial.print(",");
Serial.print(ps2x.Analog(PSS_RY), DEC);
Serial.print(",");
Serial.println(ps2x.Analog(PSS_RX), DEC);
// }
}
delay(50);
}
Here's how I did it.....
void setup()
{
Serial.begin(9600);
// retry logic to avoid a reset after power up
do
{
delay(1000);
error = ps2x.config_gamepad(13, 11, 10, 12, true, true);
if (error == 1)
Serial.println("No controller found, retry in a sec");
} while (error == 1);
if (error == 0)
{
Serial.println("Found Controller, configured successful");
Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;");
Serial.println("holding L1 or R1 will print out the analog stick values.");
Serial.println("Go to www.billporter.info for updates and to report bugs.");
}
else if (error == 2)
Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");
else if (error == 3)
Serial.println("Controller refusing to enter Pressures mode, may not support it. ");
type = ps2x.readType();
switch (type)
{
case 0:
Serial.println("Unknown Controller type");

Arduino sketch that reads serial characters as a command and does something

Currently I am trying to get a sketch working where the Arduino will read a series of characters as a command, and do something based on the series of characters sent from an iDevice. I am using an iPhone 3GS that is jailbroken to send characters to the Arduino. The method that sends the serial characters looks like the following,
- (IBAction)blinkFlow_A_LED:(id)sender {
// Method to blink the Flow_A LED on the kegboard-mini Arduino shield (<https://github.com/Kegbot/kegboard>).
NSLog(#"blink Flow_A btn pressed");
// Open serial port / interface
[serial open:B2400];
NSLog(#"%c", [serial isOpened]);
// Send serial data (TX)
char buffer [7];
buffer[0] = '{';
buffer[1] = 'b';
buffer[2] = 'l';
buffer[3] = 'i';
buffer[4] = 'n';
buffer[5] = 'k';
buffer[6] = '}';
[serial write:buffer length:7];
}
I have created a simple sketch that blinks the LED on the shield I am using, but I want the LED to blink conditionally when the button is clicked in the iOS app. The sketch that blinks the LED looks like the following,
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
This sketch is specific to making the kegboard-mini shield.
http://arduino.cc/forum/index.php?topic=157625.new;topicseen#new
This example code is in the public domain.
*/
// Pin D4 - should be connected to the flow_A LED
// Give it a name
int led = 4;
// The setup routine runs once when you press reset:
void setup() {
// Initialize the digital pin as an output.
pinMode(led, OUTPUT);
}
// The loop routine run over and over again forever:
void loop() {
digitalWrite(led, HIGH); // Turn the LED on (HIGH is the voltage level)
delay(1000); // Wait for one second
digitalWrite(led, LOW); // Turn the LED off by making the voltage LOW
delay(1000); // Wait for a second
}
That is a simple sketch!
You may want to begin with looking at the Arduino reference page: Serial
In setup(), you need at least Serial.begin(2400);.
Now, I'll suggest that reading and decoding the string "{blink}" seems like overkill. Let me suggest you send one character (for example 'b'), and detect one character, at least to start. Check out .available() and .read() on the Serial reference page. With these you can determine if a character has arrived at the Arduino and read in a single character.
You can then use these if you want to build a string of characters one at a time and compare it to String("{blink}"). This is a bit more complicated, especially if you take into account exceptions (like lost or damaged characters).
You can easily test your program using the Serial monitor tool -- just be advised that you have to hit "send" to make the characters go out.
I ended putting a simple sketch together like this which allows me to store an array of serial bytes into a String thanks to the SerialEvent example.
The sketch I am currently working with looks like the following,
/*
* kegboard-serial-simple-blink07
* This code is public domain
*
* This sketch sends a receives a multibyte String from the iPhone
* and performs functions on it.
*
* Examples:
* http://arduino.cc/en/Tutorial/SerialEvent
* http://arduino.cc/en/Serial/read
*/
// Global variables should be identified with "_"
// flow_A LED
int led = 4;
// relay_A
const int RELAY_A = A0;
// Variables from the sketch example
String inputString = ""; // A string to hold incoming data
boolean stringComplete = false; // Whether the string is complete
void setup() {
Serial.begin(2400); // Open a serial port. Sets data rate to 2400 bit/s
Serial.println("Power on test");
inputString.reserve(200);
pinMode(RELAY_A, OUTPUT);
}
void open_valve() {
digitalWrite(RELAY_A, HIGH); // Turn RELAY_A on
}
void close_valve() {
digitalWrite(RELAY_A, LOW); // Turn RELAY_A off
}
void flow_A_blink() {
digitalWrite(led, HIGH); // Turn the LED on (HIGH is the voltage level)
delay(1000); // Wait for one second
digitalWrite(led, LOW); // Turn the LED off by making the voltage LOW
delay(1000); // Wait for a second
}
void flow_A_blink_stop() {
digitalWrite(led, LOW);
}
void loop() {
// Print the string when newline arrives:
if (stringComplete) {
Serial.println(inputString);
// Clear the string:
inputString = "";
stringComplete = false;
}
if (inputString == "{blink_Flow_A}") {
flow_A_blink();
}
}
// SerialEvent occurs whenever a new data comes in the
// hardware serial RX. This routine is run between each
// time loop() runs, so using delay inside loop can delay
// response. Multiple bytes of data may be available.
void serialEvent() {
while(Serial.available()) {
// Get the new byte:
char inChar = (char)Serial.read();
// Add it to the inputString:
inputString += inChar;
// If the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}