I am working with a 3D printer that has a Gen 6 board having atmega644A. The main program on that controller can be accessed from here:
http://forums.reprap.org/read.php?13,92469
I have connected the I2C port of the Gen 6 board (Generation 6 Electronics - RepRap) with pin 4 and 5 of the Arduino Uno. The connections are fine and this is the code that I am currently running on the Arduino
#include <Wire.h>
//i2c address of the gen 6
int REP_RAP_ADDR = 4;
//my address
int CP_ADDR = 5;
void receiveEvent(int howMany)
{
while(0 < Wire.available()) // loop through all
{
char c = Wire.receive(); // receive byte as a character
Serial.print(c); // print the character
}
}
void sendGCode(char* GCode)
{
Wire.beginTransmission(REP_RAP_ADDR);
Wire.send(GCode);
Wire.endTransmission();
}
void setup()
{
Wire.begin(CP_ADDR);
Wire.onReceive(receiveEvent); // register event so that anything received on i2c is sent to the serial
//Test gcode, this should send the machine's X, Y and Z to home
sendGCode("G28 X0 Y0 Z0\n");
}
void loop()
{
}
This program is sending the three axes to home position via I2C. Now I need a digital signal from say pin 2 of the Arduino. I got it with a simple code:
int ledPin = 2; // LED connected to digital pin 2
void setup()
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}
void loop()
{
digitalWrite(ledPin, HIGH); // sets the LED on
delay(1000); // waits for a second
digitalWrite(ledPin, LOW); // sets the LED off
delay(1000); // waits for a second
}
LED is working fine but I want the main program in the Gen 6 to know that there is a digital signal at pin 2 of Arduino. So when the printer prints, the digital signal is 5V (LED is ON) and when the printer is not printing, it should be 0.
I combined these two codes and tried some routines but I am not getting the desired result
Any suggestions.....
volatile long last_received_time;
void receiveEvent(int howMany)
{
while(0 < Wire.available()) // loop through all
{
char c = Wire.receive(); // receive byte as a character
last_received_time = millis (); // remember when we last got something
}
}
void loop()
{
// light LED if we received data in the last second
if (millis () - last_received_time > 1000) // if something in the last second
digitalWrite(ledPin, HIGH);
else
digitalWrite(ledPin, LOW);
// any other stuff
}
Or more simply, but slightly more obscure:
// light LED if we received data in the last second
digitalWrite(ledPin, millis () - last_received_time > 1000);
#include <Wire.h>
#define LED_OUT 2
//i2c address of the gen 6
int REP_RAP_ADDR = 4;
//my address
int CP_ADDR = 5;
int x;
void receiveEvent(int howMany)
{
x = Wire.receive();
while(0 < Wire.available()) // loop through all
{
char c = Wire.receive(); // receive byte as a character
Serial.print(c); // print the character
}
}
void sendGCode(char* GCode)
{
Wire.beginTransmission(REP_RAP_ADDR);
Wire.send(GCode);
Wire.endTransmission();
}
void setup()
{
Wire.begin(CP_ADDR);
Wire.onReceive(receiveEvent); // register event so that anything received on i2c is sent to the serial
//Test gcode, this should send the machine's X, Y and Z to home
sendGCode("G28 X0 Y0 Z0\n");
Wire.begin(4); // join i2c bus with address #4
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
pinMode(LED_OUT, OUTPUT);
digitalWrite(LED_OUT, LOW);
x = 0;
}
void loop()
{
if (x > 0) {
for (int i=0; i<x; i++) {
digitalWrite(LED_OUT, HIGH);
delay(200);
digitalWrite(LED_OUT, LOW);
delay(200);
}
x = 0;
delay(1000);
}
delay(100);
}
I know I should not be using delays but some command that can read printing and non-printing states. But I am working on that
I am getting continuous 3.7V using the above code whether it is printing or not printing and the LED id "ON"
I tried Nick's code that he mentioned above
#include <Wire.h>
int ledPin = 2;
volatile long last_received_time;
//i2c address of the gen 6
int REP_RAP_ADDR = 4;
//my address
int CP_ADDR = 5;
void receiveEvent(int howMany)
{
while(0 < Wire.available()) // loop through all
{
char c = Wire.receive(); // receive byte as a character
Serial.print(c);
last_received_time = millis (); // remember when we last got something
}
}
void setup()
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
Wire.begin(CP_ADDR);
Wire.onReceive(receiveEvent); // register event so that anything received on i2c is sent to the serial
}
void loop()
{
// light LED if we received data in the last second
if (millis () - last_received_time > 1000) // if something in the last second
digitalWrite(ledPin, HIGH);
else
digitalWrite(ledPin, LOW);
// any other stuff
}
I am getting round about 8.8V continuous whether I am printing or not and the LED is "OFF" :~
I am getting round about 8.8V continuous whether I am printing or not and the LED is "OFF"
You are reading 8.8 volts on a 5 volt board? I think it's time to get a new meter. Or, to learn to read the one that you have.
What are you measuring, anyway?
It really isn't clear WHEN you want the pin on. Try to define it in terms of the receiveEvent code. It seems to me like that is when the pin's state is to be set.
I am measuring voltage at pin 2 which I have set as output and I want it to be 5V (LED ON)when I am printing something and 0 (LED OFF)when I am not printing.
I am trying to define it in the Receive Code but no luck. That is the reason I asked the question on the forum my friend
As I mentioned in the opening post, this is the blink code and it works fine my friend
int ledPin = 2; // LED connected to digital pin 2
void setup()
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}
void loop()
{
digitalWrite(ledPin, HIGH); // sets the LED on
delay(1000); // waits for a second
digitalWrite(ledPin, LOW); // sets the LED off
delay(1000); // waits for a second
}
I am measuring voltage at pin 2 which I have set as output and I want it to be 5V (LED ON)when I am printing something and 0 (LED OFF)when I am not printing.
As in where the comments are?
void receiveEvent(int howMany)
{
while(0 < Wire.available()) // loop through all
{
// Turn the LED on
char c = Wire.receive(); // receive byte as a character
Serial.print(c);
last_received_time = millis (); // remember when we last got something
}
// Turn the LED off
}
This test code works for me, it flashes the LED for a second whenever it receives I2C data. This is the master (simulating the reprap sending data):
#include <Wire.h>
#define SLAVE_ADDRESS 5
void setup ()
{
Wire.begin();
} // end of setup
void loop()
{
Wire.beginTransmission (SLAVE_ADDRESS);
Wire.send ("hello, world");
Wire.endTransmission ();
delay (4000);
} // end of loop
And this is the slave (receiving the data):
#include <Wire.h>
int ledPin = 13;
volatile long last_received_time;
//my address
int CP_ADDR = 5;
void receiveEvent(int howMany)
{
while(0 < Wire.available()) // loop through all
{
char c = Wire.receive(); // receive byte as a character
last_received_time = millis (); // remember when we last got something
}
}
void setup()
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
Wire.begin(CP_ADDR);
Wire.onReceive(receiveEvent); // register event so that anything received on i2c is sent to the serial
}
void loop()
{
// light LED if we received data in the last second
if (millis () - last_received_time < 1000) // if something in the last second
digitalWrite(ledPin, HIGH);
else
digitalWrite(ledPin, LOW);
// any other stuff
}
I admit I had the test backwards. In my earlier post I had:
if (millis () - last_received_time > 1000) // if something in the last second
But it should have read:
if (millis () - last_received_time < 1000) // if something in the last second
You need to make sure the the CP_ADDR is the address of the slave, and this needs to be the address that the reprap is sending to. You don't need to know the reprap address in the slave. It just responds to anything addressed to it, wherever that comes from.
#define I2CMODE 1
#define SERIALMODE 0
int inputMode = SERIALMODE;
This is for Gen 6.
Arduino has the following program at the moment
#include <Wire.h>
//i2c address of the gen 6
int REP_RAP_ADDR = 4;
//my address
int CP_ADDR = 5;
void receiveEvent(int howMany)
{
while(0 < Wire.available()) // loop through all
{
char c = Wire.receive(); // receive byte as a character
Serial.print(c); // print the character
}
}
void sendGCode(char* GCode)
{
Wire.beginTransmission(REP_RAP_ADDR);
Wire.send(GCode);
Wire.endTransmission();
}
void setup()
{
Wire.begin(CP_ADDR);
Wire.onReceive(receiveEvent); // register event so that anything received on i2c is sent to the serial
//Test gcode, this should send the machine's X, Y and Z to home
sendGCode("G28 X0 Y0 Z0\n");
}
void loop()
{
}
Now I need a digital signal at Arduino (say pin 2) that will just be 1 when printer is printing and 0 when it is not.
How to tell Gen 6 that there is a digital signal at pin 2 of Arduino and when Gen 6 is printing, it should turn the signal to be 1 (if using LED then ON) and 0 when not printing.
You've completely lost me. Is Gen 6 the reprap? Can we use consistent names?
How to tell Gen 6 that there is a digital signal at pin 2 of Arduino and when Gen 6 is printing, it should turn the signal to be 1 (if using LED then ON) and 0 when not printing.
You want to tell Gen 6 that Gen 6 is printing? Doesn't it know if it itself is printing without all this stuff?
Let me elaborate things a bit here.
I want to use a different device to print and it is other than the one connected to the reprap. In order to control that device, I need one digital and 1 analogue signal. Here is the code that I am using:
#include <Wire.h>
#include "SPI.h" // necessary library
int del=2; // used for various delays
word outputValue = 0; // a word is a 16-bit number
byte data = 0; // and a byte is an 8-bit number
int ledPin = 4; // LED connected to digital pin 4
int B = ledPin;
//i2c address of the gen 6
int REP_RAP_ADDR = 4;
//my address
int CP_ADDR = 5;
void receiveEvent(int howMany)
{
while(0 < Wire.available()) // loop through all
{
char c = Wire.receive(); // receive byte as a character
Serial.print(c); // print the character
}
}
void sendGCode(char* GCode)
{
Wire.beginTransmission(REP_RAP_ADDR);
Wire.send(GCode);
Wire.endTransmission();
}
void requestEvent()
{
Wire.beginTransmission(CP_ADDR);
Wire.send("javaid");
Wire.endTransmission();
}
void setup()
{
Wire.begin(CP_ADDR);
Wire.onReceive(receiveEvent); // register event so that anything received on i2c is sent to the serial
//Test gcode, this should send the machine's X, Y and Z to home
sendGCode("G28 X0 Y0 Z0\n");
pinMode(B, OUTPUT); // sets the digital pin as output
//set pin(s) to input and output
pinMode(10, OUTPUT);
SPI.begin(); // wake up the SPI bus.
SPI.setBitOrder(MSBFIRST);
}
void loop()
{
{
while (digitalRead(B)){ //read LED
if (B == 1) // if the value is 1
digitalWrite(B, HIGH); // sets the LED on
else
digitalWrite(B, LOW); // sets the LED off
}
}
int A;
for (int A=0; A<=4095; A++)
{
outputValue = A;
digitalWrite(10, LOW);
data = highByte(outputValue);
data = 0b00001111 & data;
data = 0b00110000 | data;
SPI.transfer(data);
data = lowByte(outputValue);
SPI.transfer(data);
digitalWrite(10, HIGH);
delay(del);
}
delay(del+25);
for (int A=4095; A>=0; --A)
{
outputValue = A;
digitalWrite(10, LOW);
data = highByte(outputValue);
data = 0b00001111 & data;
data = 0b00110000 | data;
SPI.transfer(data);
data = lowByte(outputValue);
SPI.transfer(data);
digitalWrite(10, HIGH);
delay(del);
}
delay(del+25);
}
This goes in the Arduino.
It might look a bit messy because it is a combination of 3 codes (I2C+SPI+LED)
I used SPI protocol to get an analogue signal from Arduino using MCP4921 chip. Nick helped me out with the initialization in the reprap main program. I tried declaring Analogue signal as "A" and Digital signal as "B." If I made a mistake in doing so, kindly let me know.
I am declaring A and B because I will be using them in the reprap main program.
Here is the code and in the process_g_code file, I have tried to initialize A and B (Line 41,42,79,80,386,387). I am not sure whether what I have initialized is correct or not.
http://forums.reprap.org/read.php?13,94154
And in the Arduino code, I have tried to initialize A and B as well.
And when I try printing by giving certain values to A and B, the LEDs don't respond accordingly (OFF when 0 and ON when 1).
There might be a lot wrong with what I am doing and that is exactly the reason why I am asking for help. Hope to see some positive answers
This delay is for the SPI routine. This allows the LED to fade away slowly enough.
if (B == 1)
Yes, it is intentional. Whenever I send 1, I want the LED to light up.
And I know just because something compiled, doesn't mean that it is right. But that is what I am trying to figure out. What is wrong with it and how can I make it right :~