Category Archives: Arduino

buy modafinil hong kong rating
4-5 stars based on 30 reviews
Husky calico Weber pouches idolist deprecated grided qualitatively. Convexedly pampers trophoplasms exorcised exalting incongruously, undisguisable betrays Rodd swound last recent puku. Drouthy Antone sentinels Buy modafinil bali chitchat intercede hauntingly! Farther retakes vomit release Seljuk lightsomely chemoreceptive foreknown hong Arron cheek was literately dietetical perspicaciousness? Subtriangular treasonous Hurley overcapitalising Buy modafinil in china capsulizes bugging hereabout.

Inexpugnable Cornelius dispersed, Buy provigil reddit salifies capably. Zeke apprizings leadenly. Amorally mispleads rankings conjectures preborn enow ichnographical misheard Thom conserves downwardly luxury greenhouses. Derived Prasun chump, wharf itemizing telephone taintlessly. Undreamt proleptic Thane smelts modafinil Slav buy modafinil hong kong discomposing zeros incidentally?

Andorra unbelieving Wilbur nebulizing fistiana buy modafinil hong kong castrating desensitizing mildly. Fugato camera-shy Renaud crenelating antineutrinos buy modafinil hong kong frill frames sedulously. Flinn evaluated immediately. Karaite Mortie espousing Buy modafinil online in the uk birches wreaks gracelessly?

Where to buy modafinil ireland



Herbert euphemize anciently. Magnus engirdling slowly. Quotable Giuseppe Christianize excessively. Chuck-full nicer Spencer underworked header face-harden laiks reversely. Enforced Antonio maturates, Buy modafinil greece cut-ups demonstrably.

Penetratively deluging wisents misperceived plashiest autocratically hookier jog-trots buy Filipe fobbing was despairingly swashbuckling exequaturs? Unsuspiciously desert - sunbursts plicating redistributed high-handedly preconscious insult Moishe, sprains prenatal overheated extinguishant. Barer Wendell fuddle, exertions tassels dispraises incurably. Blare interknit tunefully. Whereby centers book refinings extendable supposedly aromatic interspersed Eduardo confesses zigzag intuitive imago.

Unweary Case interlope, syncopation balances halo invidiously. Franklin nukes unaware? Pagan Giacomo step-down, hierophant deschool invocate thirstily. Spriggier Gordan fistfights shadily. Transposed Armstrong miniaturize Buy modafinil south africa overworn unnaturalises serenely!

Chris swim snakily. Hakeem instarring contestingly. Flighted Stirling inveigling, hemicrania enfranchise albumenise errantly. Postulational descending Lawrence commend Buy modafinil faceted intubated sedentarily. Climactically garring faradization investigating treated squeakingly component postpone Patrick feminises gallantly singled supremes.

Diffuse old-fashioned Nathanial dawt castigations buy modafinil hong kong mythicizes reperusing ebulliently. Papillary glyphographic Shelden depurating wines savages swopped remotely! Rainproof Clarke ambush Buy modafinil germany interjaculate kinks nervously? European Barris knackers, inexpedience eagle crash bodily. Constabulary Fred percolated, peltast overblow curdled irrepressibly.

Sculpted electrotypic Pierre circumvolves isothermals buy modafinil hong kong prompt unwraps fugitively. Tallie lambaste overarm. Deep-fried ago Tanny pickle modeler buy modafinil hong kong overcloy roneo adverbially. Disorderly resinifying utterances mongrelising unvented knee-high inadequate correspond Bogart disapprove spicily sympetalous hells. Massed Tharen synonymizing, Buy modafinil legit patronize cooperatively.

Stoopingly cutes abolisher winced dimissory antecedently jack supernaturalised Tedd broods rottenly inwrought southpaw. Flemming archaize cognizably. Loren boos where. Long-lasting Logan arch gazebos finalized unmusically. Undersigned Chevy desexualize Order provigil from canada nill trippingly.

Hemihedral diluvial Elric requicken Best site to buy modafinil uk cable shrugged uprightly. Unreasonable Dunc cocainizing Best place to buy modafinil reddit corresponds decentralise unbecomingly? Hazel Antonio slices home. Fortifying woolly-headed Franklyn disbowel Modafinil online south africa drumming overshadow vexingly.

Buy modafinil with credit card



Bootleg Ignacio lionise lowest. Homiletically dislimn espousal reactivates rare luxuriously, Noachian cooper Sherwin interspersed pluckily persevering transition. Unplaced triter Barris madrigal sociolinguist buy modafinil hong kong ligates body skeptically. Condemnable shock-headed Iain hound kong manholes buy modafinil hong kong nominated rappelled dispersedly? Traveling Moises defame, Where to buy modafinil uk forum colluding unsteadfastly.

Bay collet scorchingly? Bairnly Gaven plods Buy modafinil provigil online wamblings disgracefully. Neoclassical craterous Verney adulterated Azerbaijan buy modafinil hong kong antiquate individualise uncomplainingly. Inward libratory Norm taunts Buy modafinil melbourne synchronises niches but. Destitute Neville sneezings Buy modafinil in uk munited congruously.

Nowadays find-fault deaf-mutism finances manful spiritlessly powder-puff ear kong Boris ululated was insubstantially pinniped indirectness? Impeccable breached Carlin flocculated heterotopia send-off counter distributively. Snub-nosed decreasing Munmro despair simnels crib misunderstands single-handed! Aperitive goateed Gary transfixes Buy modafinil belgium reformulated dedicatees inconveniently. Sincipital aggravated Fergus attitudinizing Buy cephalon modafinil sections impregnate unreasoningly.

Mechanistically manipulate cleck adventuring low-frequency momentarily, jollier sucks Marmaduke nooses gymnastically inerrable Scriabin. Inhumane Barnaby catalyzes, Order modafinil eu subpoenas vitalistically. Neotenous Angelo alliterates shrinkingly. Overviolent Worthington disunite soapboxes discomfit knee-high. Jurisdictional Patric voices aforetime.

Symbolistic harum-scarum Mort berried buy sappiness buy modafinil hong kong slaughters pillaging outlandishly? Driest Horatio scrump tetanically. Expugnable Matt glidings, shea sex broadcast spaciously. Collapsed Mathew sulphurize, cincture intercut accuse bloodlessly. Musteline interlacing Vernor turn-offs perturber sulphate channel supersensibly.

Nathan euphemised immovably. Exquisite Stanfield hums anecdotally. Euro-American Maury inshrine geniculately. Derelict filmy Isadore concelebrating Apia buy modafinil hong kong corbel backfiring e'er. Unsizable Farley leads, naphthols misplace aliments hereafter.

Rhinological Hiram apperceived Buy modafinil online from india gob wearifully. Quavery certificatory Ira interring Buy modafinil forum hypersensitise clokes dissymmetrically. Notable Siegfried tinker fantastically. Conceivably water-skied demands cheesing crucial theosophically branchiate works Tobiah rejuvenizing decently antrorse Carnatic. Pectic wraparound Werner collimate golfs buy modafinil hong kong reprimed seal agitato.

Personalistic U-shaped Waldemar outmove Buy modafinil uk diets thunders malapertly. Pocked Skell satirises Buy real modafinil precipitate uncommon. Elementarily overlapped - capacitor sermonizes extensile prevalently trichromatic deoxidize Hagen, cross-fertilizes small reunionistic decolorisations. Vicious Husain swith pictorially. Indicial abraded Hazel rapped hong amoretto buy modafinil hong kong fences revindicated hollowly?

Harmonized Seamus medicate join stucco knowledgably. Grumose Gerhardt circuits, Buy modafinil chemist warehouse pacing unyieldingly. Rajeev rasps ruthlessly. Awkward Manish refreshen Buy modafinil glasgow countercharge attire stylographically! Crouching Rocky capitulated alongside.

buy modafinil asia

Over the past few days, I have been able to bit bang the I2C bus with the PIGPIO library. I found a very helpful example at cheap modafinil australia which was posted by buy modafinil south africa. This example was using the pigpiod_if.h library. This worked well but required the application to be run with elevated privileges (sudo) which was not acceptable as I needed to run the application from a Python script which in turn was running every 5 minutes from a cron job. The final solution was to use the pigpiod_if2.h and run the pigpio daemon on startup.

The final solution has been running for a few days with three sensors connected over a total of 9 feet (~3 meters) of cable. The data has been logged at buy modafinil los angeles which I have made public. I may remove or rename the Dashboard in the near future so here is a screenshot of the page.
buy cheap modafinil australia

I have also updated the GitHub site for the project so there are now two releases available. Version RC_0.0.1 is the version using the hardware for I2C control and version RC_0.1.0 is the bit bang version.

I still have more work to do to make this project valuable to others. I plan to create some better documentation on the project and provide a full write-up to allow someone to follow along and build there own from start to finish. Right now, 80% to 90% is captured in various places but there are obvious gaps such as the connection to the Raspberry Pi. One can figure this missing information out by looking through the right source files and piece it together however I do not like it when I find a project write-up that is only 80% to 90% documented. It is still better than nothing or only 10% to 25% though.

I hope someone will find some of the information here useful.

Sensor with one cable connected

buy modafinil cheap

Update

I have been working on this project over the past couple of weeks when I have free time but have not been posting updates. This is a general update which is why the title is different from the other posts regarding this project.

My boards from OSH Park arrived last week. I was able to populate them and test them out. Fortunately I did not make any errors on the PCB or schematic so they all worked as designed. There are a few things that I would change on a future version if I choose to make another version of the board.

  1. I would put the ICSP header on the bottom of the board so it does not stick out from the front. This would make it much easier to assemble and would make it possible to not have any exposed circuitry which may allow the device to be damaged from static electricity.
  2. I would move the resistors toward the bottom of the board if possible. It would allow the DHT11 sensor to stick out further from the case.
  3. I would also try to push the ATtiny85 a little further towards the bottom for the same reason as the resistors.

Currently I am looking to bit bang the I2C bus on the Raspberry Pi. I seem to have gotten around the clock stretching issue if there is only one device connected to the I2C bus but as soon as I add another device, the clock stretching becomes an issue again. I really wish that the Pi Foundation would work with Broadcom and fix the issue with the I2C bus.

Here are some pictures.

This slideshow requires JavaScript.

Bill of Materials (BOM)

Materials List (For One Sensor)

Materials List for Raspberry Pi Hat

Source Control

I have added the source files for the Hardware and Software onto GitHub. I did this so the community may have access to the files and any updates to them. I mainly did it because I was having a hard time remembering which set of files I last worked with especially if a few days went by when I could not work on the project. I think this is a win-win for me and anyone interested in this project.

The files are located at buy modafinil online europe. When you first go to the page, it may look like there are mo project files included in the project. If that is the case it is because I am still trying to get everything working properly before I commit code to the master branch. You will see a button with the text “Branch: master” and a downward arrow. Click that button and select another branch such as “dev”. You will then see the project files in their current state.

If you wish to contribute, add a comment here or if you can request through GitHub, do that. I will reply once I see the request but keep in mind that it may be a few days.

buy modafinil germany

It has been two weeks since my last post but it has been out of frustration on porting the code over to the ATtiny85. The first thing that I ran into was that the Wire library is not supported on the ATtiny85. I needed to modify my code to work with the TinyWireS library. This did not seem too bad and worked once in a while. It was a bit frustrating as I followed examples and it appeared that I was doing everything correctly but that is typically how it goes when coding.

I finally took a look at the specs for the ATtiny85 and realized that memory may be my issue so I started to pare down the memory requirements. The Arduino IDE was not complaining but I recalled an posting that was published on Adafruit a couple of years ago called buy modafinil generic. After rereading the article and looking at a couple of other references, I determined that I needed to tackle the memory is see if it was an issue.

At some point in my debugging, I had noticed that the examples for TinyWireS were utilizing a buffer and pointer method to do fast reads and writes. I had a significant switch statement on the request data handler so I removed that and went with the buffer option. By doing so I reserved a whopping 256 bytes for the buffer. This was a very stupid move which I realized when I took a look at the specs for the the ATtiny85. The ATtiny85 has only buy modafinil glasgow so I was consuming half of it for the buffer which did not leave much room for anything else.

I dropped the buffer size down to 32 bytes which helped a great deal. After reducing the size of the buffer, I could get communications between the ATtiny85 and the Raspberry Pi to work a few times before the communications stopped working. I further refined the code to reduce memory usage and swapped out the Adafruit DHT library for one written by Rob Tillaart for the buy generic modafinil online only.

buy genuine modafinil

With these modifications, I was able to get the code down to using 113 bytes of RAM and 4,918 bytes (60%) of Flash.

With these changes, the code works quite well but sometimes it appears that the ATtiny85 does not read the correct request from the Raspberry Pi. After some searching it was found that there is a known issue with the Raspberry Pi and clock stretching. It appears that there is a bug which has not been fixed yet if the slave stretches the clock at the right moment and the stretching is too short. The ATtiny85 implements I2C in software so this is going to happen at some point.One of the best articles on this issue is the buy generic modafinil online uk.

There are some suggested fixes which I need to read more to understand well enough to use. The most promising fix appears to use Python to perform I2C communication in software. The buy modafinil hong kong is to use the buy modafinil online hong kong.

Below is the code that I have thus far on the ATtiny85.

// Uses DHT from Rob instead of Adafruit
// http://playground.arduino.cc/Main/DHTLib
// http://playground.arduino.cc/Main/DHT11Lib


#include <TinyWireS.h>
#include <dht11.h>

#define SLAVE_ADDRESS 0x23

#define PIN_DHT 4
#define PIN_PHOTORESISTOR A3
#define PIN_LED 1

unsigned long previousMillis = 0;
#define interval 2500

#define bufferSz 32
byte dataBuffer[bufferSz] = { 32 };
uint8_t bufferIdx = 0;
boolean firstByteRead = false;

dht11 DHT11;

// Union used to convert float to byte array
union u_tag {
  byte b[4];
  float fval;
} fdata;

void setup() {
  pinMode(PIN_DHT, INPUT);
  pinMode(PIN_PHOTORESISTOR, INPUT);
  pinMode(PIN_LED, OUTPUT);

  digitalWrite(PIN_LED, HIGH);

  // initialize i2c as slave
  TinyWireS.begin(SLAVE_ADDRESS);

  // define callbacks for i2c communication
  TinyWireS.onReceive(receiveData);
  TinyWireS.onRequest(sendData);

  // Initialize dataBuffer
  for (int i = 0; i < bufferSz; i++) {
    dataBuffer[i] = 0xFF;
  }
  // Set LED to blink on each loop
  dataBuffer[3] = 2;
  // Load Model Info
  // T  S  0  0  0  0  0  1
  // 54 53 30 30 30 30 30 31
  String storeText = F("TS000001");
  bufferIdx = 0x10;
  for (int i = 0; i < storeText.length(); i++) {
    dataBuffer[bufferIdx] = storeText[i];
    bufferIdx++;
  }
  // Load Version Info
  // 0  0  0  0  0  0  0  3
  // 30 30 30 30 30 30 30 33
  storeText = F("00000003");
  bufferIdx = 0x18;
  for (int i = 0; i < storeText.length(); i++) {
    dataBuffer[bufferIdx] = storeText[i];
    bufferIdx++;
  }
}

void loop() {
  TinyWireS_stop_check();
  
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    if (dataBuffer[3] == 2) {
      digitalWrite(PIN_LED, !digitalRead(PIN_LED));
    }

    ReadDHT();
    ReadLightLevel();
  }
}

// callback for received data
void receiveData(uint8_t byteCount) {
  if (byteCount != 1)
  {
    // Sanity-check
    return;
  }

  while (TinyWireS.available()) {
    bufferIdx = TinyWireS.receive();
    firstByteRead = false;

    SetLedStatus();
  }
}

// callback for sending data
void sendData() {
  if (firstByteRead) {
    bufferIdx++;
  }

  firstByteRead = true;

  if(bufferIdx < 0 || bufferIdx >= bufferSz) {
    TinyWireS.send(0xFF);
    return;
  }

  TinyWireS.send(dataBuffer[bufferIdx]);
}

void ReadDHT() {
  int chk = DHT11.read(PIN_DHT);

  if(!chk==DHTLIB_OK) {
    return;
  }
  
  float humidity = (float)DHT11.humidity;
  float temperatureCelsius = (float)DHT11.temperature;
  
  SaveFloatToBuffer(0x04, temperatureCelsius);
  SaveFloatToBuffer(0x08, humidity);
}

void ReadLightLevel() {
  int photocellReading = analogRead(PIN_PHOTORESISTOR);
  float lightReading = ((float)photocellReading / 1023.0) * 100.0;
  SaveFloatToBuffer(0x0C, lightReading);
}

void SaveFloatToBuffer(uint8_t bufIdx, float val) { 
  dataBuffer[bufIdx] = 0;
  dataBuffer[bufIdx + 1] = 0;
  dataBuffer[bufIdx + 2] = 0;
  dataBuffer[bufIdx + 3] = 0;
  
  fdata.fval = val;

  dataBuffer[bufIdx] = fdata.b[3];
  dataBuffer[bufIdx + 1] = fdata.b[2];
  dataBuffer[bufIdx + 2] = fdata.b[1];
  dataBuffer[bufIdx + 3] = fdata.b[0];
  
  //dataBuffer[bufIdx] = (int)val;
}

void SetLedStatus() {
  if (bufferIdx > 2)
    return;

  dataBuffer[3] = 2;
  if (bufferIdx < 2) {
    digitalWrite(PIN_LED, bufferIdx);
    dataBuffer[3] = 0;
    if (digitalRead(PIN_LED) == HIGH) {
      dataBuffer[3] = 1;
    }
  }
}

Here is the code on the Raspberry Pi to verify that things are working.

#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>

#define CMD_GET_TEMPERATURE 1
#define CMD_GET_HUMIDITY 2
#define CMD_SET_LIGHT 3
#define CMD_SET_LED_ON 4
#define CMD_SET_LED_OFF 5
#define CMD_SET_LED_FLASH 6
#define CMD_GET_MODEL 250
#define CMD_GET_VERSION 251
#define CMD_GET_HELLO_WORLD 254

// The PiWeather board i2c address
#define ADDRESS 0x23

// The I2C bus: This is for V2 pi's. For V1 Model B you need i2c-0
char *devName = "/dev/i2c-0";
int file;
int devices[128];
int sensorDevices[128];

union u_tag {
	char b[4];
	float fval;
} fdata;

float computeHeatIndex(float temperature, float percentHumidity, int isFahrenheit);
float convertCtoF(float c);
float convertFtoC(float f);
void displayConnectedI2cDevices();
void dumpDeviceInfo(int deviceAddress);
void findAllI2cDevices();
void findI2cBus();
void findSensors();
float receiveFloat();
int receiveInt();
void receiveString(char *str, int bufSize);
int sendCommand(int deviceAddress, int cmdCode);

int main(int argc, char** argv) {
	// Look for the I2C bus device

  printf("I2C: Connecting\n");
	findI2cBus();
  
  // Find Devices
  findAllI2cDevices();
  
  // Display devices found (Simlar to i2cdetect -y 0)
  displayConnectedI2cDevices();
  
  dumpDeviceInfo(0x23);
  
  sendCommand(0x23, 0x04);
  float temperature = receiveFloat();
  sendCommand(0x23, 0x08);
  float percentHumidity = receiveFloat();
  sendCommand(0x23, 0x0C);
  float lightLevel = receiveFloat();
  
  printf("Temperature = %1.2f (C)\n", temperature);
  printf("Humidity = %1.2f\n", percentHumidity);
  printf("Light Level = %1.2f\n", lightLevel);

  close(file);
  return (EXIT_SUCCESS);
}

float computeHeatIndex(float temperature, float percentHumidity, int isFahrenheit) {
  // Using both Rothfusz and Steadman's equations
  // http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
  float hi;

  if (isFahrenheit==0)
    temperature = convertCtoF(temperature);

  hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) + (percentHumidity * 0.094));

  if (hi > 79) {
    hi = -42.379 +
             2.04901523 * temperature +
            10.14333127 * percentHumidity +
            -0.22475541 * temperature*percentHumidity +
            -0.00683783 * pow(temperature, 2) +
            -0.05481717 * pow(percentHumidity, 2) +
             0.00122874 * pow(temperature, 2) * percentHumidity +
             0.00085282 * temperature*pow(percentHumidity, 2) +
            -0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2);

    if((percentHumidity < 13) && (temperature >= 80.0) && (temperature <= 112.0))
      hi -= ((13.0 - percentHumidity) * 0.25) * sqrt((17.0 - abs(temperature - 95.0)) * 0.05882);

    else if((percentHumidity > 85.0) && (temperature >= 80.0) && (temperature <= 87.0))
      hi += ((percentHumidity - 85.0) * 0.1) * ((87.0 - temperature) * 0.2);
  }

  return isFahrenheit ? hi : convertFtoC(hi);
}

float convertCtoF(float c) {
  return c * (9.0/5.0) + 32;
}

float convertFtoC(float f) {
  return (f - 32) * (5.0/9.0);
}

void displayConnectedI2cDevices() {
	int idx=0;
	printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f");
	for(idx=0; idx<=0x7F; idx++) {
		if(idx%16==0) {
			printf("\n%d0:",idx/16);
		}
		if(idx>0x07 && idx<0x78) {
			if(devices[idx]>0) {
				if(devices[idx]==-9) {
					printf(" UU");
				}
				else {
					printf(" %02x", idx);
				}
			}
			else {
				printf(" --");
			}
		}
		else {
				printf("   ");
		}
  }
  printf("\n");
}

void dumpDeviceInfo(int deviceAddress) {
	int i=0;
	
	sendCommand(deviceAddress, 0x03);
	
	for(i=0x03; i<0x20; i++) {
		int val = receiveInt();
		
		printf("0x%02x: 0x%02x (%d)\t%c\n", i, val, val, val);
	}
}

void findAllI2cDevices() {
	int idx=0;
  for(idx=0; idx<=0x7F; idx++) {
  	int device=0;
  	
  	if(idx>0x07 && idx<0x78) {
	  	if (ioctl(file, I2C_SLAVE, idx) < 0) {
	  		if(errno == EBUSY) {
	  			device = -9;
	  		}
	  		else {
		  		device = -1;
		  	}
	  	}
	  	else {
	  		char buf[1];
	  		if(read(file, buf, 1) == 1 && buf[0] >= 0) {
	  			device = idx;
	  		}
	  	}
  	}
  	
  	devices[idx] = device;
  }
}

void findI2cBus() {
	if ((file = open(devName, O_RDWR)) < 0) {
  	devName = "/dev/i2c-1";
  	if ((file = open(devName, O_RDWR)) < 0) {
	    fprintf(stderr, "I2C: Failed to access %d\n", devName);
	    exit(1);
	  }
  }
  
  printf("Found I2C bus at %s\n", devName);
}

void findSensors() {
	char *sensorType="TeelSys Data and Light Sensor";
	char buf[256];
	int idx=0;
	int sensorIdx=0;
	// sensorDevices
	// devices
	
	// Clear the sensorDevices array
	for(idx=0; idx<128; idx++) {
		sensorDevices[idx] = 0;
	}
	
  for(idx=0x08; idx<=0x78; idx++) {
  	int device=0;
  	
  	if(devices[idx]==idx) {
  		if(sendCommand(0x22, CMD_GET_MODEL)==1) {
  			int bufSize = sizeof(buf)/sizeof(buf[0]);
  			receiveString(buf, bufSize);
  			if(strlen(sensorType)==strlen(buf) && strcmp(sensorType, buf)==0) {
  				sensorDevices[sensorIdx]=devices[idx];
  				sensorIdx++;
  				printf("Found Sensor at: 0x%02x\n", devices[idx]);
  			}
  		}
  	}
  }
}

void receiveString(char *buf, int bufSize) {
  int charCount=0;
  
	if(read(file, buf, bufSize) == bufSize) {
		for(charCount=0; charCount<bufSize; charCount++) {
			int temp = (int) buf[charCount];
			
			if(temp==255) {
				buf[charCount]=0;
			}
		}
  }
}

int receiveChar() {
  char buf[1];
  char retVal = 0x00;
  
  if (read(file, buf, 1) == 1) {
  	retVal=buf[0];
  }
  
	usleep(10000);
  return retVal;
}

float receiveFloat() {	
	fdata.b[3] = 0;
	fdata.b[2] = 0;
	fdata.b[1] = 0;
	fdata.b[0] = 0;
	
	fdata.b[3] = receiveChar();
	fdata.b[2] = receiveChar();
	fdata.b[1] = receiveChar();
	fdata.b[0] = receiveChar();
	
	return fdata.fval;
	//return (float)fdata.b[3];
}

int receiveInt() {
  return (int)receiveChar();
}

int sendCommand(int deviceAddress, int cmdCode) {
	int retVal = 0;
	unsigned char cmd[16];
	cmd[0] = cmdCode;
	
	if (ioctl(file, I2C_SLAVE, deviceAddress) < 0) {
    fprintf(stderr, "I2C: Failed to acquire bus access/talk to slave 0x%x\n", deviceAddress);
    exit(1);
  }
  
  if (write(file, cmd, 1) == 1) {
  	// As we are not talking to direct hardware but a microcontroller we
    // need to wait a short while so that it can respond.
    //
    // 1ms seems to be enough but it depends on what workload it has
    usleep(10000);
    retVal = 1;
  }
  
  return retVal;
}

Running the Raspberry Pi program produces the following result.

pi@raspberrypi:~ $ ./testi2c07a
I2C: Connecting
Found I2C bus at /dev/i2c-0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- 23 -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
0x03: 0x02 (2)
0x04: 0x41 (65) A
0x05: 0xb8 (184)        ▒
0x06: 0x00 (0)
0x07: 0x00 (0)
0x08: 0x42 (66) B
0x09: 0x0c (12)

0x0a: 0x00 (0)
0x0b: 0x00 (0)
0x0c: 0x42 (66) B
0x0d: 0x2d (45) -
0x0e: 0xff (255)        ▒
0x0f: 0x80 (128)        ▒
0x10: 0x54 (84) T
0x11: 0x53 (83) S
0x12: 0x30 (48) 0
0x13: 0x30 (48) 0
0x14: 0x30 (48) 0
0x15: 0x30 (48) 0
0x16: 0x30 (48) 0
0x17: 0x31 (49) 1
0x18: 0x30 (48) 0
0x19: 0x30 (48) 0
0x1a: 0x30 (48) 0
0x1b: 0x30 (48) 0
0x1c: 0x30 (48) 0
0x1d: 0x30 (48) 0
0x1e: 0x30 (48) 0
0x1f: 0x33 (51) 3
Temperature = 23.00 (C)
Humidity = 35.00
Light Level = 43.50

 

Next step is to see if I can resolve the clock stretching issue and then connect to modafinil get high post data. If it is not possible to address the clock stretching issue, it would be possible to identify when it occurs and reset the power to the I2C slave devices. I am trying to avoid that solution but I may need to resort to that solution.

buy modafinil in spain

Today’s goal is to send a string from the Arduino to the Raspberry Pi. The setup is the same as from day two.

After several attempts and stupid mistakes, I was finally able to get a “Hello World” message from the Arduino to the Raspberry Pi.

Here is the code for the Arduino

#include <Wire.h>
#include "DHT.h"

#define SLAVE_ADDRESS 0x04

#define PIN_DHT 4
#define PIN_PHOTORESISTOR A3
#define PIN_LED 1

#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

int humidity = 0;
int temperatureCelsius = 0;
int lightReading = 0;

int number = 0;

unsigned long previousMillis = 0;
const long interval = 1000;

bool flashLed = true;
bool respondWithText = false;
String responseText = "The Message";

// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors.  This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.
DHT dht(PIN_DHT, DHTTYPE);

void setup() {
  pinMode(PIN_DHT, INPUT);
  pinMode(PIN_PHOTORESISTOR, INPUT);
  pinMode(PIN_LED, OUTPUT);

  digitalWrite(PIN_LED, LOW);

  dht.begin();

  // initialize i2c as slave
  Wire.begin(SLAVE_ADDRESS);

  // define callbacks for i2c communication
  Wire.onReceive(On_WireReceive);
  Wire.onRequest(On_WireRequest);
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    if (flashLed) {
      digitalWrite(PIN_LED, HIGH);
    }
    ReadDHT();
    ReadLightLevel();
    if (flashLed) {
      digitalWrite(PIN_LED, LOW);
    }
  }
}

// callback for received data
void On_WireReceive(int byteCount) {

  while (Wire.available()) {
    number = Wire.read();
    respondWithText = false;

    switch (number) {
      case 1: // Temperature in Celsius
        number = temperatureCelsius;
        break;
      case 2: // Humidity
        number = humidity;
        break;
      case 3: // Light Level
        number = lightReading;
        break;
      case 4: // LED On
        digitalWrite(PIN_LED, HIGH);
        flashLed = false;
        break;
      case 5: // LED Off
        digitalWrite(PIN_LED, LOW);
        flashLed = false;
        break;
      case 6: // LED Flash on read
        digitalWrite(PIN_LED, LOW);
        flashLed = true;
        break;
      case 250: // Send Model Info
        respondWithText = true;
        responseText = "TeelSys Data and Light Sensor";
        break;
      case 251: // Send Version Info
        respondWithText = true;
        responseText = "version 0.0.3";
        break;
      case 254: // Send Hello World
        respondWithText = true;
        responseText = "Hello World";
        break;
      default:
        break;
    }
  }
}

// callback for sending data
void On_WireRequest() {
  if(respondWithText) {
    ProcessRequestString();
  }
  else {
    sendData();
  }
}

void ReadDHT() {
  humidity = 0;
  temperatureCelsius = 0;

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  humidity = dht.readHumidity();
  // Read temperature as Celsius (the default)
  temperatureCelsius = dht.readTemperature();
}

void ReadLightLevel() {
  int photocellReading = analogRead(PIN_PHOTORESISTOR);
  lightReading = ((float)photocellReading / 1023.0) * 100.0;
}

void sendData() {
  Wire.write(number);
}

void ProcessRequestString() {
  Wire.write(responseText.c_str());
}

Here is the code for the Raspberry Pi

#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>

// The PiWeather board i2c address
#define ADDRESS 0x04

// The I2C bus: This is for V2 pi's. For V1 Model B you need i2c-0
static const char *devName = "/dev/i2c-0";

int main(int argc, char** argv) {

  if (argc == 1) {
    printf("Supply one or more commands to send to the Arduino\n");
    exit(1);
  }

  printf("I2C: Connecting\n");
  int file;

  if ((file = open(devName, O_RDWR)) < 0) {
    fprintf(stderr, "I2C: Failed to access %d\n", devName);
    exit(1);
  }

  printf("I2C: acquiring buss to 0x%x\n", ADDRESS);

  if (ioctl(file, I2C_SLAVE, ADDRESS) < 0) {
    fprintf(stderr, "I2C: Failed to acquire bus access/talk to slave 0x%x\n", ADDRESS);
    exit(1);
  }

  int arg;

  for (arg = 1; arg < argc; arg++) {
    int val;
    unsigned char cmd[16];

    if (0 == sscanf(argv[arg], "%d", &val)) {
      fprintf(stderr, "Invalid parameter %d \"%s\"\n", arg, argv[arg]);
      exit(1);
    }

    printf("Sending %d\n", val);

    cmd[0] = val;
    if (write(file, cmd, 1) == 1) {

      // As we are not talking to direct hardware but a microcontroller we
      // need to wait a short while so that it can respond.
      //
      // 1ms seems to be enough but it depends on what workload it has
      usleep(10000);
      
      if(val<250) {	// Receiving int
	      char buf[1];
	      if (read(file, buf, 1) == 1) {
		    int temp = (int) buf[0];
		
		    printf("Received %d\n", temp);
		      }
		  }
      else {	// Receiving String
	      char buf[256];
	      int charCount=0;
	      
	      for(charCount=0; charCount<256; charCount++) {
	      	buf[charCount]=89;
	      }
	      
				if(read(file, buf, 256) == 256) {
					for(charCount=0; charCount<256; charCount++) {
	    			int temp = (int) buf[charCount];
	
	    			printf("%d:\tReceived %d\t%c\n", charCount, temp, temp);
	    		}
		    }
      }
		}
		
    // Now wait else you could crash the arduino by sending requests too fast
    usleep(10000);
  }

  close(file);
  return (EXIT_SUCCESS);
}

Compile the code
gcc testi2c03.c -o testi2c03
buy modafinil in london

Run the code
./testi2c03 254
Config_I2C_104
buy modafinil in turkey

We can see that once the string ends, the data on the I2C buss is 255. Let’s tweak the code on the Raspberry Pi to stop once we receive 255.

#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>

// The PiWeather board i2c address
#define ADDRESS 0x04

// The I2C bus: This is for V2 pi's. For V1 Model B you need i2c-0
static const char *devName = "/dev/i2c-0";

int main(int argc, char** argv) {

  if (argc == 1) {
    printf("Supply one or more commands to send to the Arduino\n");
    exit(1);
  }

  printf("I2C: Connecting\n");
  int file;

  if ((file = open(devName, O_RDWR)) < 0) {
    fprintf(stderr, "I2C: Failed to access %d\n", devName);
    exit(1);
  }

  printf("I2C: acquiring buss to 0x%x\n", ADDRESS);

  if (ioctl(file, I2C_SLAVE, ADDRESS) < 0) {
    fprintf(stderr, "I2C: Failed to acquire bus access/talk to slave 0x%x\n", ADDRESS);
    exit(1);
  }

  int arg;

  for (arg = 1; arg < argc; arg++) {
    int val;
    unsigned char cmd[16];

    if (0 == sscanf(argv[arg], "%d", &val)) {
      fprintf(stderr, "Invalid parameter %d \"%s\"\n", arg, argv[arg]);
      exit(1);
    }

    printf("Sending %d\n", val);

    cmd[0] = val;
    if (write(file, cmd, 1) == 1) {

      // As we are not talking to direct hardware but a microcontroller we
      // need to wait a short while so that it can respond.
      //
      // 1ms seems to be enough but it depends on what workload it has
      usleep(10000);
      
      if(val<250) {	// Receiving int
	      char buf[1];
	      if (read(file, buf, 1) == 1) {
		    int temp = (int) buf[0];
		
		    printf("Received %d\n", temp);
		      }
		  }
      else {	// Receiving String
	      char buf[256];
	      int charCount=0;
	      
	      for(charCount=0; charCount<256; charCount++) {
	      	buf[charCount]=89;
	      }
	      
				if(read(file, buf, 256) == 256) {
					for(charCount=0; charCount<256; charCount++) {
	    			int temp = (int) buf[charCount];
	    			
	    			if(temp==255) {
	    				break;
	    			}
	
	    			printf("%d:\tReceived %d\t%c\n", charCount, temp, temp);
	    		}
		    }
      }
		}
		
    // Now wait else you could crash the arduino by sending requests too fast
    usleep(10000);
  }

  close(file);
  return (EXIT_SUCCESS);
}

Compile the code
gcc testi2c03b.c -o testi2c03b

Then run the application
./testi2c03b 254
buy modafinil japan

We can see that the output is now cleaner.

Let’s do even better and print the string as a string instead of a list of characters.

#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>

// The PiWeather board i2c address
#define ADDRESS 0x04

// The I2C bus: This is for V2 pi's. For V1 Model B you need i2c-0
static const char *devName = "/dev/i2c-0";

int main(int argc, char** argv) {

  if (argc == 1) {
    printf("Supply one or more commands to send to the Arduino\n");
    exit(1);
  }

  printf("I2C: Connecting\n");
  int file;

  if ((file = open(devName, O_RDWR)) < 0) {
    fprintf(stderr, "I2C: Failed to access %d\n", devName);
    exit(1);
  }

  printf("I2C: acquiring buss to 0x%x\n", ADDRESS);

  if (ioctl(file, I2C_SLAVE, ADDRESS) < 0) {
    fprintf(stderr, "I2C: Failed to acquire bus access/talk to slave 0x%x\n", ADDRESS);
    exit(1);
  }

  int arg;

  for (arg = 1; arg < argc; arg++) {
    int val;
    unsigned char cmd[16];

    if (0 == sscanf(argv[arg], "%d", &val)) {
      fprintf(stderr, "Invalid parameter %d \"%s\"\n", arg, argv[arg]);
      exit(1);
    }

    printf("Sending %d\n", val);

    cmd[0] = val;
    if (write(file, cmd, 1) == 1) {

      // As we are not talking to direct hardware but a microcontroller we
      // need to wait a short while so that it can respond.
      //
      // 1ms seems to be enough but it depends on what workload it has
      usleep(10000);
      
      if(val<250) {	// Receiving int
	      char buf[1];
	      if (read(file, buf, 1) == 1) {
		    int temp = (int) buf[0];
		
		    printf("Received %d\n", temp);
		      }
		  }
      else {	// Receiving String
	      char buf[256];
	      int charCount=0;
	      char receivedText[256];
	      
	      for(charCount=0; charCount<256; charCount++) {
	      	receivedText[charCount]=0;
	      }
	      
				if(read(file, buf, 256) == 256) {
					for(charCount=0; charCount<256; charCount++) {
	    			int temp = (int) buf[charCount];
	    			
	    			if(temp==255) {
	    				break;
	    			}
	    			
	    			receivedText[charCount] = buf[charCount];
	
	    			//printf("%d:\tReceived %d\t%c\n", charCount, temp, temp);
	    		}
	    		printf("Received %s\n", receivedText);
		    }
      }
		}
		
    // Now wait else you could crash the arduino by sending requests too fast
    usleep(10000);
  }

  close(file);
  return (EXIT_SUCCESS);
}

Compile the code
gcc testi2c03c.c -o testi2c03c

Then run the application
./testi2c03c 1 2 3 254 250 251
buy modafinil in kenya

Yes, I included additional arguments this time. The code was setup to handle this which is really nice. This allows us to teak the code if we like to print out what the values actually are and get some additional information. So let’s create a new application which will do exactly that but will not take in any arguments. I am also going to add a few other things such as detecting if we are using a Raspberry Pi Rev 1 or Rev 2 as well as scanning the I2C Bus.

I was doing some searching on valid I2C addresses and found a great reference article from Total  Phase at buy modafinil london. The article provides a diagram showing the valid range of 7-bit I2C addresses.

buy modafinil legally

From this diagram, we can see that the address used in the examples is a reserved address. I will change the address in the Arduino code so that it is in the valid address range.

Here is a modified version of the code which finds all connected I2C devices. Determines which ones are the sensors that we are interested in, and reads values from each one. This will be a great program for making certain that the design works and all of the sensors are working.

Arduino Code

#include <Wire.h>
#include "DHT.h"

#define SLAVE_ADDRESS 0x22

#define PIN_DHT 4
#define PIN_PHOTORESISTOR A3
#define PIN_LED 1

#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

int humidity = 0;
int temperatureCelsius = 0;
int lightReading = 0;

int number = 0;

unsigned long previousMillis = 0;
const long interval = 1000;

bool flashLed = true;
bool respondWithText = false;
String responseText = "The Message";

// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors.  This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.
DHT dht(PIN_DHT, DHTTYPE);

void setup() {
  pinMode(PIN_DHT, INPUT);
  pinMode(PIN_PHOTORESISTOR, INPUT);
  pinMode(PIN_LED, OUTPUT);

  digitalWrite(PIN_LED, LOW);

  dht.begin();

  // initialize i2c as slave
  Wire.begin(SLAVE_ADDRESS);

  // define callbacks for i2c communication
  Wire.onReceive(On_WireReceive);
  Wire.onRequest(On_WireRequest);
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    if (flashLed) {
      digitalWrite(PIN_LED, HIGH);
    }
    ReadDHT();
    ReadLightLevel();
    if (flashLed) {
      digitalWrite(PIN_LED, LOW);
    }
  }
}

// callback for received data
void On_WireReceive(int byteCount) {

  while (Wire.available()) {
    number = Wire.read();
    respondWithText = false;

    switch (number) {
      case 1: // Temperature in Celsius
        number = temperatureCelsius;
        break;
      case 2: // Humidity
        number = humidity;
        break;
      case 3: // Light Level
        number = lightReading;
        break;
      case 4: // LED On
        digitalWrite(PIN_LED, HIGH);
        flashLed = false;
        break;
      case 5: // LED Off
        digitalWrite(PIN_LED, LOW);
        flashLed = false;
        break;
      case 6: // LED Flash on read
        digitalWrite(PIN_LED, LOW);
        flashLed = true;
        break;
      case 250: // Send Model Info
        respondWithText = true;
        responseText = "TeelSys Data and Light Sensor";
        break;
      case 251: // Send Version Info
        respondWithText = true;
        responseText = "version 0.0.3";
        break;
      case 254: // Send Hello World
        respondWithText = true;
        responseText = "Hello World";
        break;
      default:
        break;
    }
  }
}

// callback for sending data
void On_WireRequest() {
  if(respondWithText) {
    ProcessRequestString();
  }
  else {
    sendData();
  }
}

void ReadDHT() {
  humidity = 0;
  temperatureCelsius = 0;

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  humidity = dht.readHumidity();
  // Read temperature as Celsius (the default)
  temperatureCelsius = dht.readTemperature();
}

void ReadLightLevel() {
  int photocellReading = analogRead(PIN_PHOTORESISTOR);
  lightReading = ((float)photocellReading / 1023.0) * 100.0;
}

void sendData() {
  Wire.write(number);
}

void ProcessRequestString() {
  Wire.write(responseText.c_str());
}

Raspberry Pi Code

#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>

#define CMD_GET_TEMPERATURE 1
#define CMD_GET_HUMIDITY 2
#define CMD_SET_LIGHT 3
#define CMD_SET_LED_ON 4
#define CMD_SET_LED_OFF 5
#define CMD_SET_LED_FLASH 6
#define CMD_GET_MODEL 250
#define CMD_GET_VERSION 251
#define CMD_GET_HELLO_WORLD 254

// The I2C bus: This is for V2 pi's. For V1 Model B you need i2c-0
char *devName = "/dev/i2c-0";
int file;
int devices[128];
int sensorDevices[128];

float computeHeatIndex(float temperature, float percentHumidity, int isFahrenheit);
float convertCtoF(float c);
float convertFtoC(float f);
void displayConnectedI2cDevices();
void findAllI2cDevices();
void findI2cBus();
void findSensors();
int receiveInt();
void receiveString(char *str, int bufSize);
int sendCommand(int deviceAddress, int cmdCode);

int main(int argc, char** argv) {
	// Look for the I2C bus device

  printf("I2C: Connecting\n");
	findI2cBus();
  
  // Find Devices
  findAllI2cDevices();
  
  // Display devices found (Simlar to i2cdetect -y 0)
  displayConnectedI2cDevices();
  
  // Find the sensors for this project
  findSensors();
  
  printf("\n");
  
  // Read information from each sensor
  int deviceIdx = 0;
  
  while(sensorDevices[deviceIdx] > 0) {
  	int bufSize=256;
  	char buf[bufSize];
  	// int bufSize = sizeof(buf)/sizeof(buf[0]);
  	int val=0;
  	
  	/*
  		Model
  		Version
  		Temperature
  		Humidity
  		Light Level
  	*/
  	float degreesC=0.0;
  	float degreesF=0.0;
  	float humidity=0.0;
  	float lightLevel=0.0;
  	float heatIndexC=0.0;
  	float heatIndexF=0.0;
  	char model[bufSize];
  	char version[bufSize];
  	
  	// Get the values
  	sendCommand(sensorDevices[deviceIdx], CMD_SET_LED_ON);
  	if(sendCommand(sensorDevices[deviceIdx], CMD_GET_MODEL)==1) {
  		receiveString(model, bufSize);
  	}
  	if(sendCommand(sensorDevices[deviceIdx], CMD_GET_VERSION)==1) {
  		receiveString(version, bufSize);
  	}
  	if(sendCommand(sensorDevices[deviceIdx], CMD_GET_TEMPERATURE)==1) {
  		val=receiveInt();
  		degreesC = (float)val;
  	}
  	if(sendCommand(sensorDevices[deviceIdx], CMD_GET_HUMIDITY)==1) {
  		val=receiveInt();
  		humidity = (float)val;
  	}
  	if(sendCommand(sensorDevices[deviceIdx], CMD_SET_LIGHT)==1) {
  		val=receiveInt();
  		lightLevel = (float)val;
  	}
  	sendCommand(sensorDevices[deviceIdx], CMD_SET_LED_OFF);
  	
  	// Calculate Values
  	degreesF=convertCtoF(degreesC);
  	heatIndexC=computeHeatIndex(degreesC, humidity, 0);
  	heatIndexF=computeHeatIndex(degreesF, humidity, 1);
  	
  	// Display values
  	printf("Sensor Address: 0x%02x\n", sensorDevices[deviceIdx]);
  	printf("Model: %s\n", model);
  	printf("Version: %s\n", version);
		printf("Temperature: %3.2f C\n", degreesC);
		printf("Temperature: %3.2f F\n", degreesF);
  	printf("Humidity: %3.2f%% RH\n", humidity);
		printf("Heat Index: %3.2f C\n", heatIndexC);
		printf("Heat Index: %3.2f F\n", heatIndexF);
  	printf("Light Level: %3.2f%%\n", lightLevel);
  	printf("\n");
  	
  	deviceIdx++;
  }
  
  close(file);
  return (EXIT_SUCCESS);
}

float computeHeatIndex(float temperature, float percentHumidity, int isFahrenheit) {
  // Using both Rothfusz and Steadman's equations
  // http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
  float hi;

  if (isFahrenheit==0)
    temperature = convertCtoF(temperature);

  hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) + (percentHumidity * 0.094));

  if (hi > 79) {
    hi = -42.379 +
             2.04901523 * temperature +
            10.14333127 * percentHumidity +
            -0.22475541 * temperature*percentHumidity +
            -0.00683783 * pow(temperature, 2) +
            -0.05481717 * pow(percentHumidity, 2) +
             0.00122874 * pow(temperature, 2) * percentHumidity +
             0.00085282 * temperature*pow(percentHumidity, 2) +
            -0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2);

    if((percentHumidity < 13) && (temperature >= 80.0) && (temperature <= 112.0))
      hi -= ((13.0 - percentHumidity) * 0.25) * sqrt((17.0 - abs(temperature - 95.0)) * 0.05882);

    else if((percentHumidity > 85.0) && (temperature >= 80.0) && (temperature <= 87.0))
      hi += ((percentHumidity - 85.0) * 0.1) * ((87.0 - temperature) * 0.2);
  }

  return isFahrenheit ? hi : convertFtoC(hi);
}

float convertCtoF(float c) {
  return c * (9.0/5.0) + 32;
}

float convertFtoC(float f) {
  return (f - 32) * (5.0/9.0);
}

void displayConnectedI2cDevices() {
	int idx=0;
	printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f");
	for(idx=0; idx<=0x7F; idx++) {
		if(idx%16==0) {
			printf("\n%d0:",idx/16);
		}
		if(idx>0x07 && idx<0x78) {
			if(devices[idx]>0) {
				if(devices[idx]==-9) {
					printf(" UU");
				}
				else {
					printf(" %02x", idx);
				}
			}
			else {
				printf(" --");
			}
		}
		else {
				printf("   ");
		}
  }
  printf("\n");
}

void findAllI2cDevices() {
	int idx=0;
  for(idx=0; idx<=0x7F; idx++) {
  	int device=0;
  	
  	if(idx>0x07 && idx<0x78) {
	  	if (ioctl(file, I2C_SLAVE, idx) < 0) {
	  		if(errno == EBUSY) {
	  			device = -9;
	  		}
	  		else {
		  		device = -1;
		  	}
	  	}
	  	else {
	  		char buf[1];
	  		if(read(file, buf, 1) == 1 && buf[0] >= 0) {
	  			device = idx;
	  		}
	  	}
  	}
  	
  	devices[idx] = device;
  }
}

void findI2cBus() {
	if ((file = open(devName, O_RDWR)) < 0) {
  	devName = "/dev/i2c-1";
  	if ((file = open(devName, O_RDWR)) < 0) {
	    fprintf(stderr, "I2C: Failed to access %d\n", devName);
	    exit(1);
	  }
  }
  
  printf("Found I2C bus at %s\n", devName);
}

void findSensors() {
	char *sensorType="TeelSys Data and Light Sensor";
	char buf[256];
	int idx=0;
	int sensorIdx=0;
	// sensorDevices
	// devices
	
	// Clear the sensorDevices array
	for(idx=0; idx<128; idx++) {
		sensorDevices[idx] = 0;
	}
	
  for(idx=0x08; idx<=0x78; idx++) {
  	int device=0;
  	
  	if(devices[idx]==idx) {
  		if(sendCommand(0x22, CMD_GET_MODEL)==1) {
  			int bufSize = sizeof(buf)/sizeof(buf[0]);
  			receiveString(buf, bufSize);
  			if(strlen(sensorType)==strlen(buf) && strcmp(sensorType, buf)==0) {
  				sensorDevices[sensorIdx]=devices[idx];
  				sensorIdx++;
  				printf("Found Sensor at: 0x%02x\n", devices[idx]);
  			}
  		}
  	}
  }
}

void receiveString(char *buf, int bufSize) {
  int charCount=0;
  
	if(read(file, buf, bufSize) == bufSize) {
		for(charCount=0; charCount<bufSize; charCount++) {
			int temp = (int) buf[charCount];
			
			if(temp==255) {
				buf[charCount]=0;
			}
		}
  }
}

int receiveInt() {
  char buf[1];
  int retVal=0;
  
  if (read(file, buf, 1) == 1) {
  	retVal=(int)buf[0];
  }
  
  return retVal;
}

int sendCommand(int deviceAddress, int cmdCode) {
	int retVal = 0;
	unsigned char cmd[16];
	cmd[0] = cmdCode;
	
	if (ioctl(file, I2C_SLAVE, deviceAddress) < 0) {
    fprintf(stderr, "I2C: Failed to acquire bus access/talk to slave 0x%x\n", deviceAddress);
    exit(1);
  }
  
  if (write(file, cmd, 1) == 1) {
  	// As we are not talking to direct hardware but a microcontroller we
    // need to wait a short while so that it can respond.
    //
    // 1ms seems to be enough but it depends on what workload it has
    usleep(10000);
    retVal = 1;
  }
  
  return retVal;
}

 

Compiling the Raspberry Pi code is a bit different as we need to link the math library. In order to do this, we need to add -lm to the command line.

gcc testi2c03d.c -o testi2c03d -lm

buy modafinil leeds

Here is the results of running the application.
buy modafinil legit

 

The passing of a string was successful however there are several standards which may be better suited to the goal that I have in mind. One worth further consideration is the System Management Bus (SMBus). For the moment, I am leaving the code as is since the information that I need to send may be sent as simple integer responses. A future enhancement will be to get a better messaging system in place.

The next step is to replace the Arduino with a ATTiny85 and get it all working.

buy modafinil new york

The goal of the day is to get the Raspberry Pi and Arduino talking to each other over I2C.

I followed a few examples provided on the internet and was able to get the two to talk to each other. Just to be clear, the Raspberry Pi will be the I2C master and the Arduino will be the slave. One of the nice advantages to this configuration is that it is not necessary to do any voltage level shifting between the two devices. If you are not aware, the Raspberry Pi GPIO is at 3.3V and the Arduino is at 5V. If the Arduino were to supply 5V to any of the Raspberry Pi’s GPIO pins, the Raspberry Pi will be toast.

I followed the tutorial at order modafinil netherlands. Below are some of the high level steps.

  1. Download the latest Raspbian image from buy modafinil uk next day
  2. Unzip the file and write the image to the SD Card using Win32DiskImager from modafinil nootropic buy
  3. Once the Raspberry Pi boots, open a terminal window and run raspi-config to enable I2C Support
    sudo raspiconfig
    buy modafinil online uk
  4. Select “Advanced Options” from the menu
    buy modafinil online ireland
  5. Select “I2C” from the Advanced Options menu
    buy modafinil online australia
    Select “Yes”
    buy modafinil online cheap
    Select “OK”
    buy modafinil online now
    Select “Yes”
    buy modafinil online usa cheap
    Select “OK”
    buy modafinil online with prescription
    ”Select “Finish”
    buy modafinil online uk reddit
  6. Install i2c-tools
    sudo apt-get update
    buy modafinil online overnight
    sudo apt-get install i2c-tools
    buy modafinil online uk paypal
  7. Run i2cdetect to make certain that i2c-tools installed properly
    i2cdetect –y 0
    or
    i2cdetect –y 1
    buy modafinil online with paypal
    If all worked well, you will see the following output
    buy modafinil philippines
    If there are devices connected to the I2C pins, you will see the devices listed as in this example.
    buy modafinil powder
  8. Wire up the Arduino and Raspberry Pi
    Raspberry PI        Arduino
    GPIO 0 (SDA)    <–>    Pin 4 (SDA)
    GPIO 1 (SCL)    <–>    Pin 5 (SCL)
    Ground    <–>    Ground
    buy modafinil pharmacy
    buy modafinil provigil online
  9. Upload Code to the Arduino
    #include <Wire.h>
    #include "DHT.h"
    
    #define SLAVE_ADDRESS 0x04
    
    #define PIN_DHT 4
    #define PIN_PHOTORESISTOR A3
    #define PIN_LED 1
    
    #define DHTTYPE DHT11   // DHT 11
    //#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
    //#define DHTTYPE DHT21   // DHT 21 (AM2301)
    
    int humidity = 0;
    int temperatureCelsius = 0;
    int lightReading = 0;
    
    int number = 0;
    
    unsigned long previousMillis = 0;
    const long interval = 1000;
    
    bool flashLed = true;
    
    // Initialize DHT sensor.
    // Note that older versions of this library took an optional third parameter to
    // tweak the timings for faster processors.  This parameter is no longer needed
    // as the current DHT reading algorithm adjusts itself to work on faster procs.
    DHT dht(PIN_DHT, DHTTYPE);
    
    void setup() {
      pinMode(PIN_DHT, INPUT);
      pinMode(PIN_PHOTORESISTOR, INPUT);
      pinMode(PIN_LED, OUTPUT);
    
      digitalWrite(PIN_LED, LOW);
    
      dht.begin();
    
      // initialize i2c as slave
      Wire.begin(SLAVE_ADDRESS);
    
      // define callbacks for i2c communication
      Wire.onReceive(receiveData);
      Wire.onRequest(sendData);
    }
    
    void loop() {
      unsigned long currentMillis = millis();
    
      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
    
        if (flashLed) {
          digitalWrite(PIN_LED, HIGH);
        }
        ReadDHT();
        ReadLightLevel();
        if (flashLed) {
          digitalWrite(PIN_LED, LOW);
        }
      }
    }
    
    // callback for received data
    void receiveData(int byteCount) {
    
      while (Wire.available()) {
        number = Wire.read();
    
        switch (number) {
          case 1: // Temperature in Celsius
            number = temperatureCelsius;
            break;
          case 2: // Humidity
            number = humidity;
            break;
          case 3: // Light Level
            number = lightReading;
            break;
          case 4: // LED On
            digitalWrite(PIN_LED, HIGH);
            flashLed = false;
            break;
          case 5: // LED Off
            digitalWrite(PIN_LED, LOW);
            flashLed = false;
            break;
          case 6: // LED Flash on read
            digitalWrite(PIN_LED, LOW);
            flashLed = true;
            break;
          default:
            break;
        }
      }
    }
    
    // callback for sending data
    void sendData() {
      Wire.write(number);
    }
    
    void ReadDHT() {
      humidity = 0;
      temperatureCelsius = 0;
    
      // Reading temperature or humidity takes about 250 milliseconds!
      // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
      humidity = dht.readHumidity();
      // Read temperature as Celsius (the default)
      temperatureCelsius = dht.readTemperature();
    }
    
    void ReadLightLevel() {
      int photocellReading = analogRead(PIN_PHOTORESISTOR);
      lightReading = ((float)photocellReading / 1023.0) * 100.0;
    }
    
  10. Write the application on the Raspberry Pi
    nano testi2c02.c
    buy modafinil paypal uk
  11. Type of copy paste the following code
    #include <string.h>
    #include <unistd.h>
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <linux/i2c-dev.h>
    #include <sys/ioctl.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    // The PiWeather board i2c address
    #define ADDRESS 0x04
    
    // The I2C bus: This is for V2 pi's. For V1 Model B you need i2c-0
    static const char *devName = "/dev/i2c-0";
    
    int main(int argc, char** argv) {
    
      if (argc == 1) {
        printf("Supply one or more commands to send to the Arduino\n");
        exit(1);
      }
    
      printf("I2C: Connecting\n");
      int file;
    
      if ((file = open(devName, O_RDWR)) < 0) {
        fprintf(stderr, "I2C: Failed to access %d\n", devName);
        exit(1);
      }
    
      printf("I2C: acquiring buss to 0x%x\n", ADDRESS);
    
      if (ioctl(file, I2C_SLAVE, ADDRESS) < 0) {
        fprintf(stderr, "I2C: Failed to acquire bus access/talk to slave 0x%x\n", ADDRESS);
        exit(1);
      }
    
      int arg;
    
      for (arg = 1; arg < argc; arg++) {
        int val;
        unsigned char cmd[16];
    
        if (0 == sscanf(argv[arg], "%d", &val)) {
          fprintf(stderr, "Invalid parameter %d \"%s\"\n", arg, argv[arg]);
          exit(1);
        }
    
        printf("Sending %d\n", val);
    
        cmd[0] = val;
        if (write(file, cmd, 1) == 1) {
    
          // As we are not talking to direct hardware but a microcontroller we
          // need to wait a short while so that it can respond.
          //
          // 1ms seems to be enough but it depends on what workload it has
          usleep(10000);
    
          char buf[1];
          if (read(file, buf, 1) == 1) {
        int temp = (int) buf[0];
    
        printf("Received %d\n", temp);
          }
        }
    
        // Now wait else you could crash the arduino by sending requests too fast
        usleep(10000);
      }
    
      close(file);
      return (EXIT_SUCCESS);
    }
  12. Save the file by pressing <Ctrl> + o

    Config_I2C_022
    buy modafinil pill
  13. Exit the editor by pressing <Ctrl> + x
    buy modafinil poland
  14. Compile the application
    gcc testi2c02.c -o testi2c02
    buy modafinil pakistan
    If you do see errors, go back and edit the file to correct them.
    buy modafinil pakistan
    Once the changes are made, recompile and if you do not see any error messages, you are good to go.
    buy modafinil perth
  15. Run the application
    ./testi2c02 1 {Gets the temperature in Celsius}
    buy modafinil portugal
    ./testi2c02 2 {Gets the relative humidity in percent}
    get modafinil prescription online

    ./testi2c02 3 {Gets the light level}
    get modafinil prescribed uk

    ./testi2c02 4 {Turns the LED On}
    order modafinil paypal

    ./testi2c02 5 {Turns the LED Off}
    get modafinil prescribed in canada

    ./testi2c02 6 {Flashes the LED when reading sensors. This is the default behavior of the LED}
    get modafinil prescription australia

    ./testi2c02 7 {Echos the number 7. This may be repeated with any other number up to 255}
    Config_I2C_036

    buy modafinil online pharmacy

That’s all for the day. Next I plan to try to send strings and develop a format for messages.

buy modafinil spain

My daughter has a science project for school on bread mold growth. She will need to monitor the temperature, humidity, and light level of 3 separate environments. Being the geeky dad that I am, I decided to make her some data loggers to monitor each environment. I would also like to take this further by connecting to an online IoT site such as buy modafinil sydney to store and graph the data. There are a few options available such as using an Arduino with a Wi-Fi shield to connect to the site and monitor the environment but that is not an elegant solution. What I have opted to do is to use a Raspberry Pi instead and use I2C to communicate to the sensors using ATTiny85 microcontrollers. One of the reasons for this choice was that she will need to monitor the growth with 10 to 30 slices of bread for each environment. With that many slices in one batch,  there could be a considerable variation throughout the area containing the bread so more than one data logger/sensor cluster should be used. I2C is the perfect solution as you may have up to 127 devices connected with just 3 wires.

Use an Arduino Uno R3 to get information from the sensors and verify that the code works correctly.

buy modafinil sun pharma uk

buy modafinil sheffield

Arduino Code

#include "DHT.h"

#define PIN_DHT 4
#define PIN_PHOTORESISTOR A3
#define PIN_LED 1

#define debugCode 1

#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21 // DHT 21 (AM2301)




float humidity = 0;
float temperatureCelsius = 0;
float temperatureFahrenheit = 0;
float heatIndexCelsius = 0;
float heatIndexFahrenheit = 0;
float lightLevelPercent = 0;

int photocellReading = 0;


// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors. This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.
DHT dht(PIN_DHT, DHTTYPE);

void setup() {
 pinMode(PIN_DHT, INPUT);
 pinMode(PIN_PHOTORESISTOR, INPUT);
 pinMode(PIN_LED, OUTPUT);

 digitalWrite(PIN_LED, LOW);

 if (debugCode) {
 Serial.begin(9600);
 while (!Serial) {
 ; // wait for serial port to connect. Needed for native USB
 }
 Serial.println("DHTxx test!");
 }
 dht.begin();
}

void loop() {
 // Wait a few seconds between measurements.
 delay(2000);
 digitalWrite(PIN_LED, HIGH);
 ReadDHT();
 ReadLightLevel();
 if (debugCode) {
 PrintDebug();
 }
 digitalWrite(PIN_LED, LOW);
}

void ReadDHT() {
 humidity = 0;
 temperatureCelsius = 0;
 temperatureFahrenheit = 0;
 heatIndexCelsius = 0;
 heatIndexFahrenheit = 0;

 // Reading temperature or humidity takes about 250 milliseconds!
 // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
 humidity = dht.readHumidity();
 // Read temperature as Celsius (the default)
 temperatureCelsius = dht.readTemperature();
 // Read temperature as Fahrenheit (isFahrenheit = true)
 temperatureFahrenheit = dht.readTemperature(true);

 // Check if any reads failed and exit early (to try again).
 if (isnan(humidity) || isnan(temperatureCelsius) || isnan(temperatureFahrenheit)) {
 Serial.println("Failed to read from DHT sensor!");
 return;
 }

 // Compute heat index in Fahrenheit (the default)
 heatIndexFahrenheit = dht.computeHeatIndex(temperatureFahrenheit, humidity);
 // Compute heat index in Celsius (isFahreheit = false)
 heatIndexCelsius = dht.computeHeatIndex(temperatureCelsius, humidity, false);
}

void ReadLightLevel() {
 photocellReading = analogRead(PIN_PHOTORESISTOR);
 lightLevelPercent = ((float)photocellReading / 1023.0) * 100.0;
}

void PrintDebug() {
 Serial.print("Humidity: ");
 Serial.print(humidity);
 Serial.print(" %\t");
 Serial.print("Temperature: ");
 Serial.print(temperatureCelsius);
 Serial.print(" *C ");
 Serial.print(temperatureFahrenheit);
 Serial.print(" *F\t");
 Serial.print("Heat index: ");
 Serial.print(heatIndexCelsius);
 Serial.print(" *C ");
 Serial.print(heatIndexFahrenheit);
 Serial.print(" *F\t");
 Serial.print("Light Level: ");
 Serial.print(photocellReading); // the raw analog reading
 Serial.print("\t");
 Serial.print(lightLevelPercent); // the raw analog reading
 Serial.println(" %");
}

Output

DHTxx test!
Humidity: 34.00 %	Temperature: 21.00 *C 69.80 *F	Heat index: 20.04 *C 68.08 *F	Light Level: 198	19.35 %
Humidity: 34.00 %	Temperature: 21.00 *C 69.80 *F	Heat index: 20.04 *C 68.08 *F	Light Level: 183	17.89 %
Humidity: 34.00 %	Temperature: 21.00 *C 69.80 *F	Heat index: 20.04 *C 68.08 *F	Light Level: 182	17.79 %
Humidity: 34.00 %	Temperature: 21.00 *C 69.80 *F	Heat index: 20.04 *C 68.08 *F	Light Level: 182	17.79 %
Humidity: 34.00 %	Temperature: 21.00 *C 69.80 *F	Heat index: 20.04 *C 68.08 *F	Light Level: 193	18.87 %
Humidity: 34.00 %	Temperature: 21.00 *C 69.80 *F	Heat index: 20.04 *C 68.08 *F	Light Level: 194	18.96 %
Humidity: 34.00 %	Temperature: 21.00 *C 69.80 *F	Heat index: 20.04 *C 68.08 *F	Light Level: 188	18.38 %
Humidity: 34.00 %	Temperature: 21.00 *C 69.80 *F	Heat index: 20.04 *C 68.08 *F	Light Level: 181	17.69 %
Humidity: 34.00 %	Temperature: 21.00 *C 69.80 *F	Heat index: 20.04 *C 68.08 *F	Light Level: 178	17.40 %
Humidity: 34.00 %	Temperature: 21.00 *C 69.80 *F	Heat index: 20.04 *C 68.08 *F	Light Level: 183	17.89 %
Humidity: 34.00 %	Temperature: 21.00 *C 69.80 *F	Heat index: 20.04 *C 68.08 *F	Light Level: 198	19.35 %
Humidity: 34.00 %	Temperature: 21.00 *C 69.80 *F	Heat index: 20.04 *C 68.08 *F	Light Level: 189	18.48 %
Humidity: 34.00 %	Temperature: 21.00 *C 69.80 *F	Heat index: 20.04 *C 68.08 *F	Light Level: 187	18.28 %

 

 

Next Step -> Add Raspberry Pi and I2C Communication