00000100 11010010 & 11111111 00000000 ----------------- 00000100 00000000Using the bitwise operator & (AND) makes it become 00000100 00000000.
00000100 00000000 >> 8 ----------------- 00000100Then the bits can be shifted to the right 8 times using >>, leaving 00000100. For the second half, all that is needed is a mask of 11111111 (0xFF), leaving 11010010.
00000100 11010010 & 00000000 11111111 ----------------- 00000000 11010010
#include <Wire.h>
#include <SparkFun_APDS9960.h>
#include <SD.h>
#include <SPI.h>
#include "DRV8825.h"
#define MOTOR_STEPS 200
#define RPM 60
#define MICROSTEPS 32
#define MM_X 60
#define MM_Y 150
//pin definitions
#define STEPPER_X_DIR 7
#define STEPPER_X_STEP 6
#define STEPPER_X_EN 8
#define STEPPER_Y_DIR 4
#define STEPPER_Y_STEP 5
#define STEPPER_Y_EN 12
#define X 0
#define Y 1
#define X_DIR_FLAG -1 //1 or -1 to flip direction
#define Y_DIR_FLAG 1 //1 or -1 to flip direction
#define STEPS_PER_MM (3.75 * MICROSTEPS) //steps needed to move 1mm
#define PIXELS_W 60
#define PIXELS_H 300
#define SPACE_BETWEEN_POSITIONS_X 1
#define SPACE_BETWEEN_POSITIONS_Y .5
#define MULTIPLIER 2 //Scale each color by this amount
#define SD_CS 22
int currentPositions[] = {0, 0};
File image;
DRV8825 stepperX(MOTOR_STEPS, STEPPER_X_DIR, STEPPER_X_STEP, STEPPER_X_EN);
DRV8825 stepperY(MOTOR_STEPS, STEPPER_Y_DIR, STEPPER_Y_STEP, STEPPER_Y_EN);
SparkFun_APDS9960 apds = SparkFun_APDS9960();
uint8_t light_levels[6] = {};
uint16_t red_light = 0;
uint16_t green_light = 0;
uint16_t blue_light = 0;
unsigned long pixel_count = 0;
void setup(){
Serial.begin(115200);
SD.begin(SD_CS);
init_apds();
init_file();
take_picture();
}
void loop(){
}
void take_picture(){
unsigned long start_time = millis();
for(int row=0; row<PIXELS_H; row++){
for(int col=0; col<PIXELS_W; col++){
moveToPosition(col, row);
//delay(50);
readLightLevels();
writeLightLevels();
pixel_count++;
if(pixel_count > 1000){
image.close();
image = SD.open("pixelImg.aif", FILE_WRITE);
pixel_count = 0;
}
}
}
image.close();
moveToPosition(0, 0);
Serial.print("Image finished! It took "); Serial.print((millis() - start_time) / 1000); Serial.println(" seconds to complete.");
}
void writeLightLevels(){
image.write(light_levels, 3);
}
void readLightLevels(){
if ( !apds.readRedLight(red_light) ||
!apds.readGreenLight(green_light) ||
!apds.readBlueLight(blue_light) ) {
Serial.println("Error reading light values");
} else {
Serial.print("Red: ");
Serial.print(red_light);
Serial.print(" Green: ");
Serial.print(green_light);
Serial.print(" Blue: ");
Serial.println(blue_light);
}
light_levels[0] = red_light * MULTIPLIER;
light_levels[1] = green_light * MULTIPLIER;
light_levels[2] = blue_light * MULTIPLIER;
}
void moveToPosition(int x, int y){
int newPosX = (x-currentPositions[X])*STEPS_PER_MM*X_DIR_FLAG*SPACE_BETWEEN_POSITIONS_X;
int newPosY = (y-currentPositions[Y])*STEPS_PER_MM*Y_DIR_FLAG*SPACE_BETWEEN_POSITIONS_Y;
stepperX.move(newPosX);
stepperY.move(newPosY);
currentPositions[X] = x;
currentPositions[Y] = y;
Serial.print("Stepper positions: "); Serial.print(currentPositions[X]); Serial.print(", "); Serial.println(currentPositions[Y]);
}
void init_file(){
if(SD.exists("pixelImg.aif")){
SD.remove("pixelImg.aif");
}
//Data in MSB format
uint16_t image_w = PIXELS_W;
uint16_t image_h = PIXELS_H;
image = SD.open("pixelImg.aif", FILE_WRITE);
image.write((0xFF00 & image_w) >> 8);
image.write(0xFF & image_w);
image.write((0xFF00 & image_h) >> 8);
image.write(0xFF & image_h);
image.write(3); //bit-depth of 3 bytes (24-bits)
}
void init_apds(){
if ( apds.init() ) {
Serial.println(F("APDS-9960 initialization complete"));
} else {
Serial.println(F("Something went wrong during APDS-9960 init!"));
}
// Start running the APDS-9960 light sensor (no interrupts)
if ( apds.enableLightSensor(false) ) {
Serial.println(F("Light sensor is now running"));
} else {
Serial.println(F("Something went wrong during light sensor init!"));
}
// Wait for initialization and calibration to finish
delay(500);
}
void init_steppers(){
stepperX.begin(RPM);
stepperX.setEnableActiveState(LOW);
stepperX.enable();
stepperX.setMicrostep(MICROSTEPS);
stepperY.begin(RPM);
stepperY.setEnableActiveState(LOW);
stepperY.enable();
stepperY.setMicrostep(MICROSTEPS);
}from PIL import Image, ImageDraw
with open("PIXELIMG.AIF", 'rb') as imgFile:
img_w, img_h = 0, 0
img_w = int.from_bytes(imgFile.read(2), byteorder='big', signed = False)
print(img_w)
img_h = int.from_bytes(imgFile.read(2), byteorder='big', signed = False)
if int.from_bytes(imgFile.read(1), byteorder='big', signed = False) == 3:
img = Image.new("RGB", (img_w, img_h))
for row in range(img_h):
for col in range(img_w):
r, g, b = int.from_bytes(imgFile.read(1), byteorder='big', signed = False), int.from_bytes(imgFile.read(1), byteorder='big', signed = False), int.from_bytes(imgFile.read(1), byteorder='big', signed = False)
img.putpixel((col, row), (r, g, b))
img.show()
img.save("finished_img.bmp")(This article copied from hackster.io, Author: Arduino “having11” Guy)