Stroboscope with Arduino - arduino

first sorry for my bad english
I'm a student and I want to make a Stroboscope with Arduino for my school project
The frequency is variable between 10hz to 3000 hz and it changes using a rotary encoder
that when normally rotate the encoder 1 step frequency \pm 1hz and when rotate encoder when it pushed down frequency \pm 100hz
and Arduino make a PWM signal on pin 13 and it connect to a high power npn transistor and it turn on and off a 10 watt led
I code it using Encoder.h library by Paul Stoffregen and tone() function
but I have a PROBLEM
I code this program and upload it to Arduino Uno but it doesn't work IDK where is the problem
#include <Encoder.h>
#define ENCODER_PULSES_PER_STEP 1
int f = 10;
int direction;
Encoder myEnc(2, 3);
int t = 0;
void setup() {
pinMode(13, OUTPUT);
pinMode(4, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
direction = myEnc.read();
}
void loop() {
if (abs(direction) >= ENCODER_PULSES_PER_STEP) {
if (direction > 0) {
if (digitalRead(4) == 1) {
f++;
if (f >> 2500)f = 2500;
}
else {
f = f + 100;
if (f >> 2500)f = 2500;
}
} else {
if (digitalRead(4) == 1) {
f--;
if (f << 10)f = 10;
}
else {
f = f - 100;
}
}
myEnc.write(0);
}
tone(13, f);
}

When your program starts the function setup is executed once.
Then in an infinite loop the function loop is executed.
As you have direction = myEnc.read(); only in setup you'll only read the encoder once.
From the Encoder library's documentation:
/* Encoder Library - TwoKnobs Example
* http://www.pjrc.com/teensy/td_libs_Encoder.html
*
* This example code is in the public domain.
*/
#include <Encoder.h>
// Change these pin numbers to the pins connected to your encoder.
// Best Performance: both pins have interrupt capability
// Good Performance: only the first pin has interrupt capability
// Low Performance: neither pin has interrupt capability
Encoder knobLeft(5, 6);
Encoder knobRight(7, 8);
// avoid using pins with LEDs attached
void setup() {
Serial.begin(9600);
Serial.println("TwoKnobs Encoder Test:");
}
long positionLeft = -999;
long positionRight = -999;
void loop() {
long newLeft, newRight;
newLeft = knobLeft.read();
newRight = knobRight.read();
if (newLeft != positionLeft || newRight != positionRight) {
Serial.print("Left = ");
Serial.print(newLeft);
Serial.print(", Right = ");
Serial.print(newRight);
Serial.println();
positionLeft = newLeft;
positionRight = newRight;
}
// if a character is sent from the serial monitor,
// reset both back to zero.
if (Serial.available()) {
Serial.read();
Serial.println("Reset both knobs to zero");
knobLeft.write(0);
knobRight.write(0);
}
}
Notice the differences between your and their code.
Another more simple example from the GitHub repository to satisfy Juraj.
/* Encoder Library - Basic Example
* http://www.pjrc.com/teensy/td_libs_Encoder.html
*
* This example code is in the public domain.
*/
#include <Encoder.h>
// Change these two numbers to the pins connected to your encoder.
// Best Performance: both pins have interrupt capability
// Good Performance: only the first pin has interrupt capability
// Low Performance: neither pin has interrupt capability
Encoder myEnc(5, 6);
// avoid using pins with LEDs attached
void setup() {
Serial.begin(9600);
Serial.println("Basic Encoder Test:");
}
long oldPosition = -999;
void loop() {
long newPosition = myEnc.read();
if (newPosition != oldPosition) {
oldPosition = newPosition;
Serial.println(newPosition);
}
}
Also note that << is the binary left shift operator, not the less than operator < !
In if (f << 10)f = 10; you'll shift f 10 bits to the left. As this results in a number > 0, which is true, this condition will alway be met.
Same for >> which is the bitwise right shift operator, not greater then!

Related

Arduino send bad signal to interrupt pin

I have connected coin hopper and coin acceptor to one arduino uno, coin acceptor connected to pin 2, coin hopper to pin 3 - sensor and pin 7 - relay. When coin hopper switch relay, it is executing coininterrupt
for coin hopper I am using this script link
coin acceptor script: link
I need this 2 scripts working on 1 arduino
my code:
#define SENSOR 3
#define RELAY 7
#define ACCEPTOR 2
volatile boolean insert = false;
int pulse=0,count;
char sen;
int temp=0;
unsigned long int timer;
void setup()
{
Serial.begin(9600);
pinMode(SENSOR,INPUT_PULLUP);
pinMode(RELAY,OUTPUT);
sen=digitalRead(SENSOR);
digitalWrite(RELAY, HIGH);
attachInterrupt(digitalPinToInterrupt(ACCEPTOR), coinInterrupt, RISING);
}
void loop()
{
if (insert) {
insert = false;
Serial.println("coin");
delay(1000);
}
if(Serial.available())
{
timer=millis();
// temp is amount to dispense send to arduino
temp=Serial.parseInt();
if(temp>0){
digitalWrite(RELAY,LOW);}
}
sen=(sen<<1)|digitalRead(SENSOR);
// if hopper sensor read drop coin
if(sen==1)
{
timer=millis();
pulse++;
sen&=0x03;
Serial.println("out 1");
//if dispensed coins equal with coins to dispense stop engine
if(pulse==temp)
{
digitalWrite(RELAY,HIGH);
pulse=0;
temp=0;
}
}
// if amount dispensed is not equal with amount to dispense and engine running, stop
if((digitalRead(RELAY)==LOW)&(millis()-timer>2000))
{
digitalWrite(RELAY,HIGH);
pulse=0;
temp=0;
}
}
void coinInterrupt() {
insert = true;
}
I was trying to change pins (arduino uno support interrupts on pin 2 and 3 only) but problem still appears so I guess there is issue in the code
your sketch does not run in this state :
first fix errors :
declare insert as volatile
remove cpulse (not used anywhere)
change 'if()' to (I suppose) 'if (insert) ....'
remove stuff with 'sen' var : simply use if(digitalRead(SENSOR)) or if(!digitalRead(SENSOR))
except if you need to store relay state.
use logical operators like || or && unless you really need bitwise operations
example of result sketch :
#define SENSOR 3
#define RELAY 7
volatile boolean insert = false;
byte amountToDispense = 0;
int pulse = 0;
int temp = 0;
unsigned long int timer;
void setup()
{
Serial.begin(9600);
pinMode(SENSOR, INPUT_PULLUP);
pinMode(RELAY, OUTPUT);
digitalWrite(RELAY, HIGH);
attachInterrupt(digitalPinToInterrupt(2), coinInterrupt, RISING);
}
void loop()
{
if (insert ) {
insert = false;
Serial.println("coin");
delay(1000);
}
if (Serial.available())
{
timer = millis();
temp = Serial.parseInt();
if (temp > 0) {
//amountToDispense = Serial.read() - 48;
digitalWrite(RELAY, LOW);
}
}
if (digitalRead(SENSOR))
{
timer = millis();
pulse++;
Serial.println("out 1");
if (pulse >= temp)
{
digitalWrite(RELAY, HIGH);
pulse = 0;
temp = 0;
}
}
if (!digitalRead(RELAY) && (millis() - timer > 2000))
{
digitalWrite(RELAY, HIGH);
pulse = 0;
temp = 0;
}
}
void coinInterrupt() {
insert = true;
}
What is this supposed to do?
sen=(sen<<1)|digitalRead(SENSOR);
You init sen with digitalRead(SENSOR);
Assuming that pin is LOW when you start the sketch and turns HIGH, sen will become 1.
Next you do sen &= 0x03 so sen is still 1.
Again sen=(sen<<1)|digitalRead(SENSOR); , sen will either be 2 or 3.
Next loop run sen=(sen<<1)|digitalRead(SENSOR); sen is now 4 or 6. and so on...
I don't have time to think about what you want to achieve but this is definitely a problem as you'll only enter if (sen == 1) once and never again.
If this is not sufficient you should probably improve your post as it is unclear what arduino sends bad signal to interrup pin is supposed to mean. That doesn't make sense. Explain the expected behaviour of your program and how it behaves instead. add more comments so it becomes clear what you intend to do with each block of code so we don't have to interpret

Trying to send a float value over SPI between 2 Arduinos

I am currently trying to send a float value across two Arduinos via SPI. Currently I am working to send a static value of 2.25 across and then read it via the Serial.println() command. I would then want to pass a float value from a linear displacement sensor. My end goal is to be able to have the master ask for information, the slave gathers the appropriate data and packages it and then master receives said data and does what it needs with it.
Currently I am getting an error "call of overloaded 'println(byte [7])' is ambiguous" and I am not to sure why I am getting this error. I am currently a mechanical engineering student and I am crash-coursing myself through C/C++. I am not entirely positive about what I am doing. I know that a float is 4 bytes and I am attempting to create a buffer of 7 bytes to store the float and the '\n' char with room to spare. My current code is below.
Master:
#include <SPI.h>
void setup() {
pinMode(SS,OUTPUT);
digitalWrite(SS,HIGH);
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV4);
}
void loop() {
digitalWrite(SS,LOW);
float a = 2.25;
SPI.transfer(a);
SPI.transfer('\n');
digitalWrite(SS,HIGH);
}
My slave code is as follows:
#include <SPI.h>
byte buf[7];
volatile byte pos = 0;
volatile boolean process_it = false;
void setup() {
Serial.begin(9600);
pinMode(MISO,OUTPUT);
digitalWrite(MISO,LOW);
SPCR |= _BV(SPE); // SPI Enable, sets this Arduino to Slave
SPCR |= _BV(SPIE); // SPI interrupt enabled
}
ISR(SPI_STC_vect) {
// Interrupt Service Routine(SPI_(SPI Transfer Complete)_vector)
byte c = SPDR;
// SPDR = SPI Data Register, so you are saving the byte of information in that register to byte c
if (pos < sizeof buf) {
buf[pos++] = c;
if (c == '\n') {
process_it = true;
}
}
}
void loop() {
if (process_it = true) {
Serial.println(buf);
pos = 0;
process_it = false;
}
}
I figured out what I needed to do and I wanted to post my finished code. I also added an ability to transfer more than one float value.
Master:
#include <SPI.h>
float a = 3.14;
float b = 2.25;
uint8_t storage [12];
float buff[2] = {a, b};
void setup()
{
digitalWrite(SS, HIGH);
SPI.begin();
Serial.begin(9600);
SPI.setClockDivider(SPI_CLOCK_DIV8);
}
void loop()
{
digitalWrite(SS, LOW);
memcpy(storage, &buff, 8);
Serial.print("storage[0] = "); Serial.println(storage[0]); // the
following serial prints were to check i was getting the right decimal
numbers for the floats.
Serial.print("storage[1] = "); Serial.println(storage[1]);
Serial.print("storage[2] = "); Serial.println(storage[2]);
Serial.print("storage[3] = "); Serial.println(storage[3]);
Serial.print("storage[4] = "); Serial.println(storage[4]);
Serial.print("storage[5] = "); Serial.println(storage[5]);
Serial.print("storage[6] = "); Serial.println(storage[6]);
Serial.print("storage[7] = "); Serial.println(storage[7]);
SPI.transfer(storage, sizeof storage ); //SPI library allows a user to
transfer a whole array of bytes and you need to include the size of the
array.
digitalWrite(SS, HIGH);
delay(1000);
}
For my Slave code:
#include <SPI.h>
byte storage [8];
volatile byte pos;
volatile boolean process;
float buff[2];
void setup()
{
pinMode(MISO,OUTPUT);
SPCR |= _BV(SPE);
SPCR |= _BV(SPIE);
pos = 0;
process = false;
Serial.begin(9600);
}
ISR(SPI_STC_vect)
{
byte gathered = SPDR;
if( pos < sizeof storage)
{
storage[pos++] = gathered;
}
else
process = true;
}
void loop()
{
if( process )
{
Serial.print("storage[0] = "); Serial.println(storage[0]);
Serial.print("storage[1] = "); Serial.println(storage[1]);
Serial.print("storage[2] = "); Serial.println(storage[2]);
Serial.print("storage[3] = "); Serial.println(storage[3]);
Serial.print("storage[4] = "); Serial.println(storage[4]);
Serial.print("storage[5] = "); Serial.println(storage[5]);
Serial.print("storage[6] = "); Serial.println(storage[6]);
Serial.print("storage[7] = "); Serial.println(storage[7]);
memcpy(buff,&storage,8);
Serial.print("This is buff[0]");Serial.println(buff[0]);
Serial.print("This is buff[1]");Serial.println(buff[1]);
storage[pos] = 0;
pos = 0;
process = false;
}
}
The immediate problem is that Serial.print doesn't know what to do with a byte array. Either declare it as a char array or cast it in the print statement:
char buf[7];
OR
Serial.print((char*) buf);
Either way, though, it's not going to show up as a float like you want.
An easier way to do all this is to use memcpy or a union to go back and forth between float and bytes. On the master end:
uint8_t buf[4];
memcpy(buf, &a, 4);
Then use SPI to send 4 bytes. Reverse it on the peripheral end.
Note that sending '\n' as the termination byte is a bad idea because it can lead to weird behavior, since one of the bytes in the float could easily be 0x0a, the hexadecimal equivalent of '\n'.

Modbus floating point conversion

I am using Arduino modbus library for measuring string current using hall sensor.Here library downloaded.Modbus library .I have sensor data in floating value & the library store the value in integer format.
question :
how can save the sensor value into integer format
How can assign user defined address. start address like 4000h instead of 0000H
code
#include <avr/wdt.h>
#include"glob.h"
//#define ID 1
void Device_ID_Reading()
{
for(row=0;row<9;row++)
{
digitalWrite(SO_enable,array1[row][0]);
digitalWrite(S1_enable,array1[row][1]);
digitalWrite(S2_enable,array1[row][2]);
Status_Out[row]=digitalRead(Read_IDstatus);
Device_ID =1*Status_Out[0]+2*Status_Out[1]+4*Status_Out[2]+8*Status_Out[3]+16*Status_Out[4]+32*Status_Out[5]+64*Status_Out[6]+128*Status_Out[7];
Serial.print("Device_ID");
Serial.print(row);
Serial.print(":\t");
Serial.println(Device_ID);
}
}
int8_t state = 0;
Modbus slave(Device_ID, 0, 0);
unsigned long tempus;
// data array for modbus network sharing
uint16_t au16data[30];
void Take_Reading()
{
for(row=0;row<9;row++)
{
// int k=(8*array[row][0]+4*array[row][1]+2*array[row][2]+1*array[row][3]);
// digitalWrite(Enablepin,array[row][0]);
digitalWrite(SO_enable,array1[row][1]);
digitalWrite(S1_enable,array1[row][2]);
digitalWrite(S2_enable,array1[row][3]);
//delay(100);
Sensor_Value0=analogRead(A0);
Sensor_Value1=analogRead(A5);
Mux1_array[row]=(Sensor_Value0 * ARDUINO_ANALOG_SCALING);
Mux2_array[row]=(Sensor_Value1 * ARDUINO_ANALOG_SCALING);
Current_Value1[row]= (Mux1_array[row]*35.1428571429)-87.6571428571;
Current_Value2[row]= (Mux2_array[row]*35.1428571429)-87.6571428571;
Current_Value3[row]=(Mux3_array[row]*35.1428571429)-87.6571428571;
}
}
void setup()
{
wdt_enable(WDTO_8S);
slave.begin( 9600 );
tempus = millis() + 100;
pinMode(3,OUTPUT);
pinMode(SO_enable, OUTPUT) ;// pin can enable/disable using digital IO 7 of arduino
pinMode(S1_enable, OUTPUT) ;// pin can enable/disable using digital IO 6 of arduino
pinMode(S2_enable, OUTPUT) ;// pin can enable/disable using digital IO 5 of arduino
// pinMode(Enablepin, OUTPUT) ;// pin can enable/disable using digital IO 4 of arduino
pinMode(A0, INPUT) ;
pinMode(A1, INPUT) ;
pinMode(A2,INPUT);
// Serial.begin(9600);
}
void loop()
{
digitalWrite(3,HIGH);
// wdt_reset();
Take_Reading();
Device_ID_Reading();
state = slave.poll( au16data,30 );
if (state > 4) {
tempus = millis() + 50;
digitalWrite(13, HIGH);
}
if (millis() > tempus) digitalWrite(13, LOW );
Modbus_call();
}
void Modbus_call()
{
/*reading of coil where i can succefully read value*/
au16data[1]=(int)(100*Current_Value1[0]);
au16data[2]=(int)(100*Current_Value1[1]);
au16data[3]=(int)(100*Current_Value1[3]);
au16data[4]=(int)(100*Current_Value1[4]);
au16data[5]=(int)(100*Current_Value1[5]);
au16data[6]=(int)(100*Current_Value1[6]);
au16data[7]=(int)(100*Current_Value1[7]);
au16data[8]=(int)(100*Current_Value1[8]);
au16data[9]=(int)(100*Current_Value2[0]);
au16data[10]=(int)(100*Current_Value2[1]);
au16data[11]=(int)(100*Current_Value2[2]);
au16data[12]=(int)(100*Current_Value2[3]);
au16data[16]=(int)(100*Current_Value2[4]);
au16data[17]=(int)(100*Current_Value2[5]);
au16data[18]=(int)(100*Current_Value2[6]);
au16data[19]=(int)(100*Current_Value2[7]);
uint16_t calcCRC( au16data[15]);
au16data[13] = slave.getInCnt();
au16data[14] = slave.getOutCnt();
au16data[15] = slave.getErrCnt();
}
Is there any other library where i can use the floating point directly.
Modbus as a protocol does not directly support floats. However you can put float data into adjacent registers. Use type punning to put the float data into your registers and pull it out on the other side.
union Pun {float f; uint32_t u;};
void encodeFloat(uint16_t *regs, float x)
{
union Pun pun;
pun.f = x;
regs[0] = (pun.u >> 16) & 0xFFFFU;
regs[1] = pun.u & 0xFFFFU;
}
float decodeFloat(const uint16_t *regs)
{
union Pun pun;
pun.u = ((uint32_t)regs[0] << 16) | regs[1];
return pun.f;
}
You would use it like so:
void Modbus_call()
{
/*reading of coil where i can succefully read value*/
encodeFloat(&au16data[ 0], Current_Value1[0]);
encodeFloat(&au16data[ 2], Current_Value1[1]);
encodeFloat(&au16data[ 4], Current_Value1[2]);
/* And so on... */
}

Light flashes more times than it's asked to

I am trying to get my LED to flash when the hypotenuse enters certain range. But it seems like it's passing that value of hypotenuse range more times than it should. LED Flashes for about good 30 -40 times before it goes back to being normal. Not sure how to fix this problem.
This is my processing code:
import processing.serial.*;
float r_height; // rise of the slope
float r_width; // run of the slope
float hypotnuse; // hypotenuse of the right angle
int d = 20; // diameter of the chocolate
float x ; // x of the chocolate destination
float y ; // y of the chocolate destination
int ledGlow; // how much the LED will glow
Serial myPort; // serial port object
void setup () {
size (510, 510); // size of the canvas
String portName = Serial.list()[8]; // my arduino port
myPort = new Serial(this, portName, 9600);
background (0); // color of the background
fill(204); // fill of the ellipse
ellipseMode (CORNER); //Ellipse mode
x = 0; //The placement on initial X for chocolate
y = 0; // the placement on initial Y for chocolate
ellipse (x, y, d, d); // ellipse
frameRate (30);
}
void draw () {
r_height = mouseY - y; // rise
r_width = mouseX - x; //run
hypotnuse = sqrt (( (sq(r_height)) + (sq (r_width)))); //A^2 +B^2 = C^2
ledGlow = 255 - (round (hypotnuse/2.84)); // flipping the values
myPort.write(ledGlow); // The value being sent to the Arduino
println (ledGlow);
}
This is the arduino code:
float val; // Data received from the serial port
int ledPin = 9;
void setup() {
pinMode(ledPin, OUTPUT); // Set pin as OUTPUT
Serial.begin(9600); // Start serial communication at 9600 bps
}
void loop() {
if (Serial.available())
{ // If data is available to read,
val = Serial.read(); // read it and store it in val
// long steps2move = val.toInt();
}
if (val > 230) {
analogWrite (ledPin, 255) ; // I have already tried digitalWrite
delay (100);
analogWrite (ledPin, 1) ;
delay (100);
}
else if (val < 230) {
analogWrite(ledPin, val);
}
}
UPDATED ARDUINO:
float val; // Data received from the serial port
int ledPin = 9; // Set the pin to digital I/O 13
unsigned long currentTime = 0;
unsigned long pastTime = 0;
int currentState = 0;
int wait = 0;
void setup() {
pinMode(ledPin, OUTPUT); // Set pin as OUTPUT
Serial.begin(9600); // Start serial communication at 9600 bps
}
void loop() {
if (Serial.available())
{ // If data is available to read,
val = Serial.read(); // read it and store it in val
// long steps2move = val.toInt();
}
if (val > 230) {
pastTime = currentTime;
currentTime = millis();
unsigned long timePassed = currentTime - pastTime;
if(timePassed >= wait)
{
switch(currentState )
{
case 0:
digitalWrite(9, HIGH);
wait = 500;
currentState = 1;
break;
case 1:
digitalWrite(9, LOW);
wait = 500;
currentState = 0;
break;
}
}
}
else if (val < 230) {
analogWrite(ledPin, val/2);
}
}
The processing code is presumably writing out to serial constantly. However, when the hypotenuse enters the range you've set, the Arduino has those delay() calls. I think that will be causing it to lag behind, so it keeps flashing while it clears the backlog of serial data that came in during the delays.
I think a better approach is to avoid using delay() at all, so the Arduino can handle the serial data as fast as possible. On each loop, it should first grab the latest serial data (if there is any). Based on that, it should figure out and store what the LED should currently be doing (i.e. whether it should be flashing, or else what brightness it should be).
After that (regardless of whether any serial data was actually received), the LED can be updated from the stored state. Remember not to use delay() for the flashing though. Instead, you could keep track of the last time it flashed on, and figure out if 100 ms has passed since then (using millis()). If so, switch it off. If another 100 ms has passed, switch it back on.
This approach decouples the flash timing from the serial data, so hopefully it should work better.

Send over infrared on Arduino

I need to transmit an infrared signal using the Arduino to run a Samsung TV.
I tried the following code:
// Lucas Eckels
// Http://lucaseckels.com
// IR remote control emitter for NEC protocol remote, as described at
// Http://www.sbprojects.com/knowledge/ir/nec.htm
// Tested on a Samsung LCD TV.
#include <util/delay.h>
#define IR_PIN 13
// With CONTINOUS defined, the first command is repeated continuously until
// You reset the Arduino. Otherwise, it sends the code once, then waits for
// Another command.
#define CONTINUOUS
// Times are in microseconds
#define ON_START_TIME 4500
#define OFF_START_TIME 4500
#define ON_TIME 580
#define OFF_TIME_ONE 1670
#define OFF_TIME_ZERO 540
#define DEVICE_1 7
#define DEVICE_2 7
void setup() {
pinMode (IR_PIN, OUTPUT);
digitalWrite(IR_PIN, LOW);
Serial.begin(9600);
delay(1000);
Serial.write("Starting up..\n");
}
byte command = 0;
int commandCount = 0;
bool commandReady = false;
void loop() {
if (commandReady) {
Serial.print("Writing command");
Serial.print(command, DEC);
Serial.print("\n");
writeStart();
// Writing device code
writeByte(DEVICE_1);
writeByte(DEVICE_2);
// Writing command code
writeByte(command);
writeByte(~command);
writeEnd();
delay(100);
#ifndef CONTINUOUS
commandReady = false;
command = 0;
commandCount = 0;
#endif
return;
}
if (Serial.available () > 0) {
// Read in a 3-digit decimal command code.
byte incoming = Serial.read();
if (incoming <= '9 ' || incoming >= '0') {
command *= 10;
command += incoming - '0 ';
++commandCount;
}
if (commandCount == 3) {
commandReady = true;
}
}
}
void writeStart() {
modulate(ON_START_TIME);
delayMicroseconds(OFF_START_TIME);
}
void writeEnd() {
modulate(ON_TIME);
}
void writeByte(byte val) {
// Starting with the LSB, write out the
for (int i = 0x01; i & 0xFF; i <<= 1) {
modulate(ON_TIME);
if (val & i) {
delayMicroseconds (OFF_TIME_ONE);
} else {
delayMicroseconds (OFF_TIME_ZERO);
}
}
}
void modulate(int time) {
int count = time / 26;
byte portb = PORTB;
byte portbHigh = portb | 0x20; // Pin 13 is controlled by 0x20 on PORTB.
byte portbLow = portb & ~0x20;
for (int i = 0; i <= count; i++) {
// The ideal version of this loop would be:
// DigitalWrite(IR_PIN, HIGH);
// DelayMicroseconds(13);
// DigitalWrite(IR_PIN, LOW);
// DelayMicroseconds(13);
// But I had a hard time getting the timing to work right. This approach was found
// Through experimentation.
PORTB = portbHigh;
_delay_loop_1(64);
PORTB = portbLow;
_delay_loop_1(64);
}
PORTB = portb;
}
The code compiles but is not working for me.
I wrote this to control an LG TV and Sony Amplifier. You would just need to save your own raw codes to the header file and off you go:
https://github.com/gotnull/SiriProxy-TV-Control/blob/master/arduino-remote/Remote/Remote.pde
// This procedure sends a 38KHz pulse to the IRledPin
// for a certain # of microseconds. We'll use this whenever we need to send codes
void pulseIR(long microsecs) {
// we'll count down from the number of microseconds we are told to wait
cli(); // this turns off any background interrupts
while (microsecs > 0) {
// 38 kHz is about 13 microseconds high and 13 microseconds low
digitalWrite(IRledPin, HIGH); // this takes about 3 microseconds to happen
delayMicroseconds(10); // hang out for 10 microseconds
digitalWrite(IRledPin, LOW); // this also takes about 3 microseconds
delayMicroseconds(10); // hang out for 10 microseconds
// so 26 microseconds altogether
microsecs -= 26;
}
sei(); // this turns them back on
}
I'd also recommend taking a read through Ladyada's wonderful tutorial:
Sensor tutorials - IR remote receiver/decoder tutorial
DelayMicroseconds is fairly accurate, and will be precise enough for your task. However you are right in staying away from DigitalWrite. It takes about 50 times as many clock-cycles to complete compared to direct port assignment (PORTB=... ) which takes exactly one. You will only be able to time a 38MHz pulse that way. I don't know what your _delay_loop_1 does, but everything else seems okay. (aside from the "i + +" but that's a cut'n'paste typo I guess)
Have you checked that it actually lights up? a phone or cheap digicam will actually show you the IR on the screen.

Resources